我的代码是一个多进程并发服务器进程,它使用系统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