Странные проблемы подпроцессов и сигналов - PullRequest
0 голосов
/ 03 февраля 2020

Я хочу реализовать простую систему баз данных. Родительский процесс получает запросы сокетов от клиента, открывает соответствующую базу данных в соответствии с этими запросами и распределяет их по дочернему процессу: если дочерний процесс уже существует, дескриптор сокета может быть напрямую отправлен дочернему процессу через конвейерную связь; если дочерний процесс не существует, его можно создать, а дескриптор сокета также можно отправить по конвейеру. Give.

Подпроцесс поддерживает пул потоков. Когда подпроцесс получает дескриптор сокета от родительского процесса, он разбудит поток в состоянии ожидания на pthread_kill() (подпроцесс регистрирует соответствующую функцию процессора сигналов).

Но я нахожу очень странное явление : когда подпроцесс создается впервые, хотя он отправляет сигнал соответствующему потоку, его тело потока не будет выполнено, а будет выполнена только функция процессора сигналов, и тогда весь доступ сокетов к подпроцессу будет нормальным.

Я не могу придумать решение. Мне приходилось думать, что я пытаюсь поспать секунду с функцией sleep(), прежде чем подпроцессы войдут в цикл. Теперь это снова нормально.

Я надеюсь получить вашу помощь.

Код, связанный с родительским процессом:

 case OPE_DB:
           printf("OPEN DB ` %s ` from [%s]\n",cl_request.db_name,addrStr);
           temp_dms_p=dms;
           prex_len=strlen(DB_PREX);
           while(temp_dms_p!=NULL){
               if(strcmp(temp_dms_p->db_name+prex_len,cl_request.db_name)==0 )
                   break;
               temp_dms_p=temp_dms_p->db_manager_next;
           }
           if(temp_dms_p==NULL){
               printf("db dont exist!\n");
               rep_err("db dont exist!\n",&cl_response);
               write(cl_socket_fd,&cl_response,sizeof(cl_response));
               return -1;
           }

           fs_ipc_data.event_type=FS_CONN;
           fs_ipc_data.cl_socket=cl_socket_fd;

           if(temp_dms_p->isOpenned==TRUE){
               if(write(temp_dms_p->pipe_fd[1],&fs_ipc_data,sizeof(fs_pipe_ipc_st))!=sizeof(fs_pipe_ipc_st) && errno==EPIPE){
                    temp_dms_p->isOpenned=FALSE;
                    close(temp_dms_p->pipe_fd[1]);
                    cur_pro_num--;
               }else
                     return 0;

           }
           if(cur_pro_num>=pro_max){
                 rep_err("The quatily of the fork reaches the limit !\n",&cl_response);
                 write(cl_socket_fd,&cl_response,sizeof(cl_response));
                 return -1;
           }

           if(pipe(temp_dms_p->pipe_fd)==-1){
               rep_err("something wrong occured!\n",&cl_response);
               write(cl_socket_fd,&cl_response,sizeof(cl_response));
               return -1;
           }

           temp_dms=*temp_dms_p;
           temp_dms.db_manager_next=NULL;

           switch(fork()){
               case -1:
                   temp_dms_p->isOpenned=FALSE;
                   printf("on fork() error \n");
                   break;
               case 0:
                   printf("open db:%s\n",temp_dms.db_name);
                   if(close(temp_dms_p->pipe_fd[1])==-1)
                       errExit("on close pipe_fd\n");
                   tb_handler(temp_dms);
                   _exit(0);
               default:
                   if(close(temp_dms_p->pipe_fd[0])==-1){
                       printf("close fd[0] error!\n");
                       close(temp_dms_p->pipe_fd[1]);
                       return -1;
                     }
                   if(write(temp_dms_p->pipe_fd[1],&fs_ipc_data,sizeof(fs_pipe_ipc_st))!=sizeof(fs_pipe_ipc_st) && errno==EPIPE){
                      close(temp_dms_p->pipe_fd[1]);
                      return -1;
                     }
                   temp_dms_p->isOpenned=TRUE;
                   cur_pro_num++;
                   return 0;
           }

           break;

код прецессии сына :

#include"./db_manager.h"
#define TB_RECORD_LINE_SIZE 100
#define TB_PRE_MIN_SIZE 8192

extern int init_tb_list(tb_manager_st **);
extern int init_thr_list(thr_manager_st **);

extern int thr_max;
extern int tb_max_num;

static char  buf[TB_RECORD_LINE_SIZE];

void tb_handler(db_manager_st dms){
    tb_manager_st * t_ms;
    thr_manager_st * thr_ms,*temp_thr_ms;
    fs_pipe_ipc_st ipc_data;
    rep_head cl_response;
    if(chdir(dms.db_name)==-1)
        errExit("chdir error\n");

    if(init_tb_list(&t_ms)!=0)
        errExit("init_tb_list return nonzero!\n");
    if(init_thr_list(&thr_ms)!=0)
        errExit("init_thr_list return nonzero!\n");

    //sleep(1);                        //wo ye bu zhi dao wei shen me ,di yi ci fork shi,huan xing bu liao zi jin cheng, shui yi xia jiu hao le
    while(1){
       if(read(dms.pipe_fd[0],&ipc_data,sizeof(fs_pipe_ipc_st))==sizeof(fs_pipe_ipc_st)){
           switch(ipc_data.event_type){
               case FS_TEST:
                   printf("Test\n");
                   break;
               case FS_CONN:
                   printf("Conn\n");

                   temp_thr_ms=thr_ms;
                   printf("thr_ms[0] tid:%ld\n",thr_ms->tid);
                   while(temp_thr_ms!=NULL){
                       if(temp_thr_ms->cl_socket_fd!=0){
                           printf("!=0\n");
                           temp_thr_ms=temp_thr_ms->next;
                           continue;
                       }
                       printf("mtid:%ld,cur_tid:%ld\n",pthread_self(),temp_thr_ms->tid);
                       temp_thr_ms->cl_socket_fd=ipc_data.cl_socket;
                       if(pthread_kill(temp_thr_ms->tid,SIGUSR2)!=0){
                           printf("pthread_kill error!\n");
                           rep_err("something wrong occured!\n",&cl_response);
                           write(ipc_data.cl_socket,&cl_response,sizeof(cl_response));
                           continue;
                       }
                       break;
                   }
                   if(temp_thr_ms==NULL){
                           rep_err("reaches the connection limit!\n",&cl_response);
                           write(ipc_data.cl_socket,&cl_response,sizeof(cl_response));
                           continue;
                   }
                   rep_suc(&cl_response,0);
                   write(ipc_data.cl_socket,&cl_response,sizeof(rep_head));

                   break;
               case FS_EXIT:
                   printf("Exit\n");
                   break;
           }
       }else{
           printf("exit\n");
           _exit(1);
       }

    }
}



void *
connect_handler(void * arg){
    thr_manager_st * thr_ms;
    thr_ms=(thr_manager_st *)arg;
   // printf("tid:%ld\n",pthread_self());
    for(;;){
       pause();
       printf("aware once:%ld!\n",thr_ms->tid);
       thr_ms->cl_socket_fd=0;
    }
}

static void
thr_sig_handler(int sig){
   printf("sig_handler\n");
}

int
init_thr_list(thr_manager_st ** thr_ms){
    struct sigaction sa;
    thr_manager_st * temp_thr_ms;
    int i=1;

    sa.sa_handler=thr_sig_handler;
    sa.sa_flags=0;
    sigemptyset(&sa.sa_mask);
    if(sigaction(SIGUSR2,&sa,NULL)==-1)
        errExit("sigcation error!\n");

    *thr_ms=NULL;
    while(i++<=thr_max){
       temp_thr_ms=malloc(sizeof(thr_manager_st));
       temp_thr_ms->cl_socket_fd=0;
       if(pthread_create(&temp_thr_ms->tid,NULL,connect_handler,temp_thr_ms)!=0)
           errExit("create pthread error!\n");
      // printf("init_tid:%ld\n",temp_thr_ms->tid);
       temp_thr_ms->next=*thr_ms;
       *thr_ms=temp_thr_ms;
    }
    if(*thr_ms==NULL)
        return -1;
    return 0;
}

Использование sleep():

[baba@localhost mydbs]$ ./db_main
//read db.config……
//read db.record......
Waiting for connection,port:9999
connection from:[socket_id:5,(localhost.localdomain:51784)]
OPEN DB ` test5 ` from [(localhost.localdomain:51784)]
open db:db_test5
Conn
thr_ms[0] tid:140663201380096
mtid:140663277074240,tid:140663201380096
sig_handler
aware once:140663201380096!
//[check dms]:
  //      db:db_test4:
  //      db:db_test3:
 //       db:db_test5:
//Test
connection from:[socket_id:5,(localhost.localdomain:51786)]
OPEN DB ` test5 ` from [(localhost.localdomain:51786)]
Conn
thr_ms[0] tid:140663201380096
mtid:140663277074240,tid:140663201380096
sig_handler
aware once:140663201380096!
//[check dms]:
  //      db:db_test4:
 //       db:db_test3:
//        db:db_test5:
//Test

Не использовать sleep ():


[baba@localhost mydbs]$ ./db_main
//read db.config……
//read db.record......
Waiting for connection,port:9999
connection from:[socket_id:5,(localhost.localdomain:51788)]
OPEN DB ` test5 ` from [(localhost.localdomain:51788)]
open db:db_test5
Conn
thr_ms[0] tid:139884971738880
mtid:139885047433024,cur_tid:139884971738880
sig_handler
//[check dms]:
  //      db:db_test5:
 //       db:db_test3:
//        db:db_test4:
//Test
connection from:[socket_id:5,(localhost.localdomain:51790)]
OPEN DB ` test5 ` from [(localhost.localdomain:51790)]
Conn
thr_ms[0] tid:139884971738880
!=0
mtid:139885047433024,cur_tid:139884980131584
sig_handler
aware once:139884980131584!
//[check dms]:
  //      db:db_test5:
 //       db:db_test3:
//        db:db_test4:
//Test
^C
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...