下面是C代码:
// my_repro.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
volatile sig_atomic_t counter = 1;
void handler(int sig) {
counter = 15;
return;
}
int main(void) {
pid_t pid;
printf("%d\n", counter);
fflush(stdout);
signal(SIGINT, handler);
if ((pid = fork()) == 0) {
while(1) {};
}
kill(pid, SIGINT);
printf("%d\n", ++counter);
fflush(stdout);
}
字符串
我编译:第一个月
并运行:./my_repro.c
个
我用的是x86-64的Mac。
为什么它会输出:
1
2
型
而不是:
1
16
型
?
我认为对全局变量使用volatile sig_atomic_t
的目的是为了让信号处理程序可以改变这些全局变量的状态。
2条答案
按热度按时间cigdeys31#
sig_atomic_t
需要存储在共享内存段中,以便在父进程和子进程之间共享。在父节点向子节点发送信号之前,需要进行一些仔细的同步。下面的示例代码在派生子进程之前阻塞信号,并让子进程调用sigsuspend
来解除阻塞信号并等待它。在父节点向子节点发送信号之后,还需要进行一些同步。下面的示例代码只是让子进程在捕获信号后正常退出,父进程等待子进程终止,然后再次使用共享的sig_atomic_t
。如果希望保持子进程运行,则可以使用更复杂的同步机制。字符串
iqjalb3h2#
看起来问题是分叉进程获得所有变量的副本,* 包括 * 全局变量。如果我这样做:
字符串
然后我得到
型
如所料。