[英]Why is the global variable shared after fork()?
据我了解,在 fork() 发生后,父进程和子进程共享变量,直到其中一个进程发生一些修改。 一旦父级或子级修改它,就会生成并分配一个副本——因此,它们不再“共享”变量。 (即Fork() 和全局变量)所以,我认为以下代码会打印出“050”:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
int counter = 0;
void handler1(int sig) {
printf("%d", counter);
kill(getpid(), SIGUSR2);
}
void handler2(int sig) {
counter = 5;
printf("%d", counter);
}
int main(int argc, char *argv[])
{
int pid;
signal(SIGUSR1, handler1);
signal(SIGUSR2, handler2);
if ((pid = fork())) {
kill(pid, SIGUSR1);
}
else {
wait(0);
counter++;
printf("%d", counter);
}
return 0;
}
但相反,它打印“056”。 这好像是:
子打印 0。子将“计数器”的值修改为 5。子打印 5。不知何故,修改会影响父的“计数器”……而父打印 6。
这怎么可能? 是不是因为修改是在信号处理程序内部进行的? 如果是这样,信号处理程序引起的更改是否会影响访问该全局变量的所有进程?
不知何故,修改会影响父级的“计数器”......并且父级打印 6。
这就是你感到困惑的地方。 父进程不打印任何东西; 只有子进程在打印,并且只有它的counter
变量被修改。
实际流量:
一个进程调用fork()
。 现在有两个进程,父进程和子进程。
父SIGUSR1
使用kill()
向子SIGUSR1
发送SIGUSR1
,然后退出。 请记住,父级中的fork()
返回子级的 pid,子级中返回 0。 (或者它失败并返回一个您应该检查的错误。)
子SIGUSR1
的SIGUSR1
处理程序函数打印counter
的值(当前为 0),然后调用SIGUSR2
处理程序。 那个将counter
设置为 5,然后打印出来。
最后, main()
中的孩子的身体运行。 wait()
被调用并返回错误,因为孩子没有自己的孩子(这可能发生在信号处理程序运行之前或之后)。 然后它将counter
增加到 6,打印它,然后退出。
printf()
中的信号处理程序和printf()
的顺序不是固定的,因为您没有做任何事情来同步; 多次运行该程序可能会产生不同的结果。 在信号处理程序中使用printf()
和其他 stdio 函数是不安全的,可能会导致非常奇怪的行为。 有关详细信息,请参阅 Linux信号安全手册页,以及从信号处理程序调用的安全列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.