首页 > 解决方案 > fork() 重复进程,线程呢?

问题描述

我正在弄清楚带有 fork 的线程是如何工作的,这是我试图理解的代码。(请原谅代码中的错误)

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
void* f(int threadnum) {
    int i;
    i = fork();

    if (i == 0) {   // child process
        printf("(%d) child says hello\n", threadnum);
    } else {
        printf("(%d) parent[%d] says hello\n", threadnum, i);
        wait(NULL);
        int new = fork();
        if (new != 0){
            printf("(%d) parent[%d] says hello to grandchild\n", threadnum, new);
            wait(NULL);
        } else 
            printf("(%d) grandchild says hello\n", threadnum);
    }
}

 int main () 
{
    pthread_t pid[2]; 
    for (int i = 0; i < 2; i++) {
        pthread_create(&pid[i], NULL, f, (void *)i);
        printf("Thread created with id [%li]\n", pid[i]);
    }
    for (int i = 0; i < 2; i++){
        pthread_join(pid[i], NULL);
    }
    return 0;
}

这是我得到的输出:

Thread created with id [663664384]
Thread created with id [655271680]
(1) parent[5690] says hello
(0) parent[5691] says hello
(1) child says hello
(1) parent[5692] says hello to grandchild
(0) child says hello
(1) grandchild says hello
(0) parent[5693] says hello to grandchild
(0) grandchild says hello

我认为线程的工作方式与必须分叉两次调用 f() 没有太大区别。如果单个线程执行exit(),那么整个过程呢?如果单个线程调用 exec(),那么其他线程呢?

标签: cmultithreadingpthreadsfork

解决方案


您不会看到当前代码的行为有太大差异。线程和进程之间的主要区别在于内存布局。

子线程使用与父线程相同的虚拟内存,而子进程拥有自己的 VM 副本。exit()因此,您可以通过从代码中的不同位置调用来查看线程和分叉行为的差异。

如果您从父级打招呼exit()的地方(本质上是从新线程)调用,进程将立即退出,因为它使用的是同一个虚拟机。而如果从子进程调用时打招呼(来自新进程的意思),其余的打印语句将继续,因为子进程有自己的内存空间。exit()


推荐阅读