如何解决分叉具有多线程C的进程
我正在遵循有关pthread
和fork
的指南,但是对于以下代码的工作方式感到困惑。
以下代码来自https://github.com/angrave/SystemProgramming/wiki/Pthreads%2C-Part-2%3A-Usage-in-Practice
#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",(char*)arg);
return NULL;
}
int main() {
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,sleepnprint,"New Thread One");
pthread_create(&tid2,"New Thread Two");
child = fork();
printf("%d:%s\n","fork()ing complete");
sleep(3);
printf("%d:%s\n","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
- 8970是父进程吗?
- 在网站上说子进程只有一个线程,这是否意味着子进程不会进入
sleepnprint
函数? - 为什么在
8970:fork()ing complete
之前打印8973:fork()ing complete
8970: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",(char*)arg);
return NULL;
}
int main() {
pthread_t tid1,tid2;
pthread_create(&tid1,NULL,sleepnprint,"New Thread One");
pthread_create(&tid2,"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:%s\n","Child process finished");
exit(0);
}
// Father process
printf("%d:%s\n","fork()ing complete");
sleep(3);
printf("%d:%s\n","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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。