【发布时间】:2018-03-19 17:00:41
【问题描述】:
我的代码是一个多进程并发服务器进程,它使用系统V消息队列与客户端进程通信,一个客户端有一个子进程。首先我想要等待不再使用的子进程.当我用 SIG_IGN 设置 SIGCHLD 处理程序时,程序可以正常工作,但当我捕获 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,"file doesn't exist\n");这里缺少大小参数。 (你的编译器至少应该产生一个警告) -
对不起,这是我的拼写错误。我想修复,但它似乎不支持修改。我的客户端和服务器程序可以编译成功
-
不应编译。更改编译器标志。对于 gcc,添加
-Wall -Wpedantic -
你误会了我的意思,在我的电脑里这个拼写是正确的,我只是在网站上拼错了。对不起,我不擅长英语,希望你能明白我的意思说
标签: c unix signals message-queue