繁体   English   中英

为什么在fork()之后共享全局变量?

[英]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。 (或者它失败并返回一个您应该检查的错误。)

SIGUSR1SIGUSR1处理程序函数打印counter的值(当前为 0),然后调用SIGUSR2处理程序。 那个将counter设置为 5,然后打印出来。

最后, main()中的孩子的身体运行。 wait()被调用并返回错误,因为孩子没有自己的孩子(这可能发生在信号处理程序运行之前或之后)。 然后它将counter增加到 6,打印它,然后退出。

printf()中的信号处理程序和printf()的顺序不是固定的,因为您没有做任何事情来同步; 多次运行该程序可能会产生不同的结果。 在信号处理程序中使用printf()和其他 stdio 函数是不安全的,可能会导致非常奇怪的行为。 有关详细信息,请参阅 Linux信号安全手册页,以及从信号处理程序调用的安全列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM