在看了Unix编程第10章信号之后,自己动手使用信号实现父子进程同步,书上10-24程序中使用sigsuspend函数在子进程运行时,将父进程挂起,直到接收到子进程发来的信号SIGUSR1,测试时出现段错误,使用gdb查看bt信息:
(gdb) run test.c
Starting program: /home/fairy/Unix_Code/Chapter9/SecSolution/10-61 test.cProgram received signal SIGUSR1, User defined signal 1.
0x00007ffff7a427e6 in __GI___sigsuspend (set=0x602260 <waitmask>) at ../sysdeps/unix/sysv/linux/sigsuspend.c:30
30 ../sysdeps/unix/sysv/linux/sigsuspend.c: No such file or directory.
跟踪堆栈信息:
(gdb) bt
#0  0x00007ffff7a427e6 in __GI___sigsuspend (set=0x602260 <waitmask>) at ../sysdeps/unix/sysv/linux/sigsuspend.c:30
#1  0x000000000040160c in wait_child () at 10-61.c:156
#2  0x000000000040145c in main (argc=2, argv=0x7fffffffdcb8) at 10-61.c:76得知是wait_child()函数中sigsuspend出现问题。
我的tell_wait()、tell_parent()、wait_child()函数如下:sig_usr信号处理程序119 static void sig_usr(int signo)
120 {
121     flag=1;
122 }
123 tell_wait()函数
125 void tell_wait(void)
126 {
127     signal(SIGUSR1,&sig_usr);
128     signal(SIGUSR2,&sig_usr);
129 
130     sigemptyset(&oldmask);
131     sigemptyset(&newmask);
132     sigemptyset(&waitmask);
133 
134     sigaddset(&newmask,SIGUSR1);             //初始时屏蔽两个信号,父进程挂起时没有屏蔽
135     sigaddset(&newmask,SIGUSR2);
136     
137     if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0){
138         err_sys("获取当前信号屏蔽字失败!\n");
139     }
140 
tell_parent()函数:
//通知父进程SIGUSR1
145 void tell_parent(pid_t pid)
146 {
147     kill(pid,SIGUSR1);
148 }
wait_child()函数:
//等待子进程运行结束
151 int  wait_child(void)
152 {
153     //sigaddset(&waitmask,SIGUSR2);//屏蔽SIGUSR2
154     while(flag==0){
155         //pr_mask("父进程等待:");
156         if(sigsuspend(&waitmask)!=-1){
157             err_sys("sigsuspend error!\n");
158         }
159     }
160     
161     parent_count++;
162     flag=0;
163 
164     if(sigprocmask(SIG_SETMASK,&oldmask,NULL)==-1){
165         err_sys("恢复屏蔽字失败!\n");
166     }
167 
168     return parent_count;
169 }                  问题出现在sigsuspend函数这里,之前使用打印屏蔽字时可以正常使用,恳请各位大佬指点!!

解决方案 »

  1.   

    好像应该是先把别的信号屏蔽了,再调用sigsuspend:    sigset_t mask;
        sigfillset(&mask);
        sigdelset(&mask, SIGUSR1);    if (sigprocmask(SIG_SETMASK, &mask, NULL) < 0) {
            perror("sigprocmask()");
            exit(EXIT_FAILURE);
        }    sigsuspend(&mask);
      

  2.   

    大佬,我是在tell_wait中屏蔽了SIGUSR1,而在wait_child中使用sigprocmask,此时屏蔽的信号字是空的,我测试不论waitmask是不是含有屏蔽值,都会提示./sysdeps/unix/sysv/linux/sigsuspend.c: No such file or directory.
    大佬,求帮助~
      

  3.   

    初步断定是gdb链接时产生的问题,参考https://github.com/arsv/riscv-qemu/issues/2