分叉具有多个线程C的进程



我正在遵循关于pthreadfork的指南,但我对以下代码的工作方式感到困惑。以下代码来自https://github.com/angrave/SystemProgramming/wiki/Pthreads%2C-第2部分%3A在实践中的应用

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
static pid_t child = -2;
void *sleepnprint(void *arg) {
printf("%d:%s starting up...n", getpid(), (char *) arg);
while (child == -2) {sleep(1);} /* Later we will use condition variables */
printf("%d:%s finishing...n",getpid(), (char*)arg);
return NULL;  
}
int main() {
pthread_t tid1, tid2;
pthread_create(&tid1,NULL, sleepnprint, "New Thread One");
pthread_create(&tid2,NULL, sleepnprint, "New Thread Two");

child = fork();
printf("%d:%sn",getpid(), "fork()ing complete");
sleep(3);

printf("%d:%sn",getpid(), "Main thread finished");

pthread_exit(NULL);
return 0; /* Never executes */
}
8970:New Thread One starting up...
8970:fork()ing complete
8973:fork()ing complete
8970:New Thread Two starting up...
8970:New Thread Two finishing...
8970:New Thread One finishing...
8970:Main thread finished
8973:Main thread finished
  1. 8970是父进程吗
  2. 从网站上看,它说孩子只有一个线程,那么这是否意味着孩子进程不去sleepnprint函数
  3. 为什么8970:fork()ing complete8973:fork()ing complete8970:New Thread Two starting up...之前打印?线程和进程的顺序是随机的吗

主线程(main((函数(使用pthread_create((创建两个线程,但由于它们是线程,所以它们是同一进程的一部分(getpid((为主线程和次线程返回8970(。如果您想要任务标识符,请在线程入口点调用gettid(((您将分别获得8971和8972(。

然后,父进程分叉,父进程和子进程都在main((函数中继续。它们分别显示它们的pid:8970和8973。

当一个多线程进程分叉时,只有调用线程是"叉";"再现";在子进程中(父进程的其他线程没有分叉:子进程是单线程的,直到它在自己一侧创建新线程为止(。因此,在您的示例中,编号为8973的子进程没有在父进程(编号为8970(中创建的两个线程。

是的,所有线程和进程都是并行运行的(按任何顺序(。

为了说明前面的内容,这里有一个稍微增强的程序版本:

#define _GNU_SOURCE  // To get gettid()
#include <pthread.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static volatile pid_t child = -2;
void *sleepnprint(void *arg)
{
printf("Process %d, Task %d:%s starting up...n", getpid(), gettid(), (char *) arg);
// This is not the best way to synchronize threads but this works here:
// once the main thread returns from fork(), child = pid of child process
// (i.e. != -2)
while (child == -2) {sleep(1);} /* Later we will use condition variables */
printf("Process %d, Task %d:%s finishing...n", getpid(), gettid(), (char*)arg);
return NULL;  
}
int main() {
pthread_t tid1, tid2;
pthread_create(&tid1,NULL, sleepnprint, "New Thread One");
pthread_create(&tid2,NULL, sleepnprint, "New Thread Two");

child = fork();
// In father process: child = child process pid
// In child process: child = 0
if (child == 0) {
// This is the child process
printf("%d:%sn",getpid(), "Child process finished");
exit(0);
}
// Father process
printf("%d:%sn",getpid(), "fork()ing complete");
sleep(3);
printf("%d:%sn",getpid(), "Main thread finished");
pthread_exit(NULL);
return 0; /* Never executes */
}

编译和执行:

$ gcc example.c -l pthread
$ ./a.out
Process 6141, Task 6142:New Thread One starting up...
Process 6141, Task 6142:New Thread One finishing...
Process 6141, Task 6143:New Thread Two starting up...
Process 6141, Task 6143:New Thread Two finishing...
6144:Child process finished
6141:fork()ing complete
6141:Main thread finished

相关内容

  • 没有找到相关文章

最新更新