Я хочу реализовать простую систему баз данных. Родительский процесс получает запросы сокетов от клиента, открывает соответствующую базу данных в соответствии с этими запросами и распределяет их по дочернему процессу: если дочерний процесс уже существует, дескриптор сокета может быть напрямую отправлен дочернему процессу через конвейерную связь; если дочерний процесс не существует, его можно создать, а дескриптор сокета также можно отправить по конвейеру. 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