问题描述
以下代码摘自 CS:APP3e 第 809 页的练习题 8.8
volatile long counter = 2;
void handler1(int sig)
{
sigset_t mask,prev_mask;
Sigfillset(&mask);
Sigprocmask(SIG_BLOCK,&mask,&prev_mask); /* Block sigs */
Sio_putl(--counter);
Sigprocmask(SIG_SETMASK,&prev_mask,NULL); /* Restore sigs */
_exit(0);
}
int main()
{
pid_t pid;
sigset_t mask,prev_mask;
printf("%ld",counter);
fflush(stdout);
signal(SIGUSR1,handler1);
if ((pid = fork()) == 0) {
while(1) {};
}
Kill(pid,SIGUSR1);
Waitpid(-1,NULL,0);
Sigfillset(&mask);
Sigprocmask(SIG_BLOCK,&prev_mask); /* Block sigs */
printf("%ld",++counter);
Sigprocmask(SIG_SETMASK,NULL); /* Restore sigs */
exit(0);
}
任务是找到这个程序的打印输出。根据教科书,答案应该是“213”。给出的解释如下:
父进程首先打印“2”,然后派生子进程,子进程无限循环。然后父节点向子节点发送信号并等待它终止。孩子捕获信号(中断无限循环),递减计数器(从初始值 2),打印“1”,然后终止。父节点收割子节点后,它会增加计数器(从初始值 2 开始),打印“3”,然后终止。
我不明白对 printf 的最后一次调用如何将 counter 的初始值设为 2。在孩子捕获 SIGUSR1 信号并将控制权传递给 handler1,它将全局变量递减为 1,并因 _exit(0) 系统调用而终止。父进程收割终止的子进程后,调用
printf("%ld",++counter);
应该使用 counter 的值作为 1 并打印“2”。因此,打印输出应该是“212”。谁能解释为什么打印“213”?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)