fork()复制进程,线程如何?

时间:2019-11-18 03:39:21

标签: c multithreading pthreads 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(),那么其他线程呢?

1 个答案:

答案 0 :(得分:2)

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

子线程使用与父线程相同的虚拟内存,而子进程拥有其自己的VM副本。因此,您可以通过在代码的各个位置调用exit()来了解线程和fork行为的差异。

如果您从 parent说打招呼的地方(本质上是从新线程)调用exit(),因为该进程使用的是相同的VM。而如果exit()是从 child调用打招呼(意思是新流程)而来的,则其余print语句将继续,因为child具有自己的内存空间。