我的代碼是一個多進程併發服務器進程,它使用系統V消息隊列與客戶端進程進行通信,一個客戶端與一個子進程通信。 第一個我希望等待子進程不再使用。當我設置SIGCHLD處理程序與SIG_IGN,程序可以正常工作,但總是錯誤,當我趕上SIGCHLD,錯誤是客戶端進程阻塞在mesrcv系統調用,這意味着服務器不會發送消息給客戶端。 秒,當我輸入^ \來退出我的客戶端進程時,服務器進程終止,我使它成爲一個守護進程並使它永遠在背景中運行,所以我想也許這個waitpid調用正在等待自己?這是不可能的爲什麼我的信號處理程序不僅僅是等待子進程?
//this is signal handler
void handler(int sig){
waitpid(-1,NULL,WNOHANG);
}
//in main
//my first step is make it become a daemon(fork twice)
//my first step is using record lock to ensure only one running
//then set signal handler and process message send by client
if(signal(SIGCHLD,SIG_IGN)==SIG_ERR){
//because its a daemon,so no tty and redirct stdin,stdout,stderr to /dev/null
syslog(LOG_ERR|LOG_USER,"set signal handler failed");
return errno;
}
//now process the client request ,client message contant a client sysV message queue id and a filename,server report the file whether exist
int pid;
while((rcv_size=msgrcv(srvmqid,&srvbuf,1024,0)!=-1){
if(0==rcv_size)
continue;
if((pid=fork())<=0){
clibuf.mtype=srvbuf.mtype;
climsqid=strtol(srvbuf.filename,&filename,10);
if((fd=open(filename,O_RDONLY)==-1)
snprintf(clibuf.filename,"file doesn't exist\n");
else{
snprintf(clibuf.filename,"file exist\n");
close(fd);
}
if(msgsnd(climsqid,&clibuf,1024,0)==-1)
syslog(LOG_ERR,"send message to client pid:%d failed,srvbuf.mtype);
if(pid==0) //if pid<0,then no child process is created
exit(0);
}
}
客戶端進程的核心代碼都低於
int main(int argc,char*argv[]){
//first ,i create the client message queue and open public serve message queue,then send struct msgbuf struct to server,the mtype is pid,the buffer behind mtype is composed by client message queue key and filename(no space between them)
while(1){
if(msgsnd(sermsqid,&sndbuf,1024,0)!=-1){
if(msgrcv(climsqid,&rcvbuf,1024,0,0)!=-1)
printf("type:%ld,file state:%s\n",rcvbuf.mtype,rcvbuf.filename);
else
printf("receive message failed\n");
}
printf("input a filename you want to search:(^e to quit)");
fgets(filename,1024,stdin);
if(filename[0]==5)//^e is 5
break;
filename[strlen(filename)-1)='\0';
snprintf(sndbuf.filename,1024,"%d%s",climsqid,filename);
}
msgctl(climsqid,IPC_RMID,NULL);
return errno;
}
'snprintf(clibuf.filename,「文件不存在\ n」);'size參數在這裏丟失。 (你的編譯器至少應該生成一個警告) – wildplasser
對不起,這是我的拼寫錯誤。我想修復,但它似乎不支持修改。我的客戶端和服務器程序可以編譯成功 – Peterhaiker
不應該編譯。更改你的編譯器標誌。對於海灣合作委員會,添加'-Wall -Wpedantic' – wildplasser