用多线程 C 分叉一个进程
fork a process with multiple thread 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",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:%s\n",getpid(), "fork()ing complete");
sleep(3);
printf("%d:%s\n",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
- 8970是父进程吗?
- 从网站上看,子进程只有单线程,那么子进程不去
sleepnprint
函数吗?
- 为什么
8970:fork()ing complete
8973:fork()ing complete
在 8970:New Thread Two starting up...
之前打印?线程和进程的顺序是随机的吗?
主线程(main()函数)在线程入口点创建两个线程pthread_create() but as they are threads, they are part of the same process (getpid() returns 8970 for the main thread and the secondary threads). If you want the task identifiers, call gettid()(分别得到8971和8972)
然后,父进程forks,父进程和子进程都在main()函数中继续。他们分别显示他们的pid:8970和8973。
当一个多线程进程fork时,只有调用线程在子进程中被“复制”(父进程的其他线程没有被fork:子进程在创建新线程之前是单线程的)它的一侧)。因此,在您的示例中,子进程编号 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:%s\n",getpid(), "Child process finished");
exit(0);
}
// Father process
printf("%d:%s\n",getpid(), "fork()ing complete");
sleep(3);
printf("%d:%s\n",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
我正在遵循有关 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",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:%s\n",getpid(), "fork()ing complete");
sleep(3);
printf("%d:%s\n",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
- 8970是父进程吗?
- 从网站上看,子进程只有单线程,那么子进程不去
sleepnprint
函数吗? - 为什么
8970:fork()ing complete
8973:fork()ing complete
在8970:New Thread Two starting up...
之前打印?线程和进程的顺序是随机的吗?
主线程(main()函数)在线程入口点创建两个线程pthread_create() but as they are threads, they are part of the same process (getpid() returns 8970 for the main thread and the secondary threads). If you want the task identifiers, call gettid()(分别得到8971和8972)
然后,父进程forks,父进程和子进程都在main()函数中继续。他们分别显示他们的pid:8970和8973。
当一个多线程进程fork时,只有调用线程在子进程中被“复制”(父进程的其他线程没有被fork:子进程在创建新线程之前是单线程的)它的一侧)。因此,在您的示例中,子进程编号 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:%s\n",getpid(), "Child process finished");
exit(0);
}
// Father process
printf("%d:%s\n",getpid(), "fork()ing complete");
sleep(3);
printf("%d:%s\n",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