如何加入其中有分叉的线程?
How to join a thread which have fork in it?
情况如下
{
...
pthread_create(thread_id, NULL, thread_fun, NULL);
pthread_join(thread_id, NULL);
...
}
void * thread_fun(void * arg)
{
if(fork())
{
printf("In Parent\n");
pthread_exit(NULL);
}
else
{
printf("In Child\n");
pthread_exit(NULL);
}
}
如何使用 pthread_join() 以便我可以在线程中等待子进程和父进程?
将所有线程置于无限循环中,然后使用ps
、top
、htop
或类似工具检查整个程序状态。你会发现子进程只有一个线程,而父进程有(至少)两个。
现在,关于你的问题如何使用pthread_join()
等待子进程,你根本做不到,因为你只能用它来等待同一个进程中的线程。您可以等待子进程终止 (waitpid()
)。
如果以上没有回答你的问题(有点不清楚,因为你想"wait for both child and parent process",这是我想知道从哪个进程的上下文)退后一步并描述更高将你想要达到的目标水平。换句话说,这可能是所谓的"XY Problem"。对那个术语做一点研究,无论如何学习和理解都是一件好事。
基本上有两种方法可以做到这一点。您可以让子线程在退出之前等待子进程,或者您可以将子进程的 PID 传递给父线程,以便它可以等待。这是第一种方法:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, thread_fun, NULL);
pthread_join(thread, NULL);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
printf("In Parent\n");
waitpid(pid, NULL, 0);
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
这是第二个:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
struct locked_pid {
sem_t sem;
pid_t pid;
};
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
struct locked_pid s;
sem_init(&s.sem, 0, 0);
pthread_create(&thread, NULL, thread_fun, &s);
sem_wait(&s.sem);
waitpid(s.pid, NULL, 0);
pthread_join(thread, NULL);
sem_destroy(&s.sem);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
struct locked_pid *s = arg;
s->pid = pid;
sem_post(&s->sem);
printf("In Parent\n");
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
请注意,第一个比第二个简单得多。这是因为在第二种情况下,您需要一个信号量,以便父进程知道何时写入子 PID。
顺便说一下,在将此代码用于任何重要的事情之前,您应该了解以下两点:
- 它没有任何错误检查,即使它使用的大部分功能都可能失败。
- POSIX says "If a multi-threaded process calls fork() ... the child process may only execute async-signal-safe operations until such time as one of the exec 函数被调用。”这意味着你不应该做
printf("In Child\n");
.
情况如下
{
...
pthread_create(thread_id, NULL, thread_fun, NULL);
pthread_join(thread_id, NULL);
...
}
void * thread_fun(void * arg)
{
if(fork())
{
printf("In Parent\n");
pthread_exit(NULL);
}
else
{
printf("In Child\n");
pthread_exit(NULL);
}
}
如何使用 pthread_join() 以便我可以在线程中等待子进程和父进程?
将所有线程置于无限循环中,然后使用ps
、top
、htop
或类似工具检查整个程序状态。你会发现子进程只有一个线程,而父进程有(至少)两个。
现在,关于你的问题如何使用pthread_join()
等待子进程,你根本做不到,因为你只能用它来等待同一个进程中的线程。您可以等待子进程终止 (waitpid()
)。
如果以上没有回答你的问题(有点不清楚,因为你想"wait for both child and parent process",这是我想知道从哪个进程的上下文)退后一步并描述更高将你想要达到的目标水平。换句话说,这可能是所谓的"XY Problem"。对那个术语做一点研究,无论如何学习和理解都是一件好事。
基本上有两种方法可以做到这一点。您可以让子线程在退出之前等待子进程,或者您可以将子进程的 PID 传递给父线程,以便它可以等待。这是第一种方法:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
pthread_create(&thread, NULL, thread_fun, NULL);
pthread_join(thread, NULL);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
printf("In Parent\n");
waitpid(pid, NULL, 0);
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
这是第二个:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
struct locked_pid {
sem_t sem;
pid_t pid;
};
void *thread_fun(void *arg);
int main(void) {
pthread_t thread;
struct locked_pid s;
sem_init(&s.sem, 0, 0);
pthread_create(&thread, NULL, thread_fun, &s);
sem_wait(&s.sem);
waitpid(s.pid, NULL, 0);
pthread_join(thread, NULL);
sem_destroy(&s.sem);
return 0;
}
void *thread_fun(void *arg) {
pid_t pid = fork();
if(pid) {
struct locked_pid *s = arg;
s->pid = pid;
sem_post(&s->sem);
printf("In Parent\n");
pthread_exit(NULL);
} else {
printf("In Child\n");
exit(0);
}
}
请注意,第一个比第二个简单得多。这是因为在第二种情况下,您需要一个信号量,以便父进程知道何时写入子 PID。
顺便说一下,在将此代码用于任何重要的事情之前,您应该了解以下两点:
- 它没有任何错误检查,即使它使用的大部分功能都可能失败。
- POSIX says "If a multi-threaded process calls fork() ... the child process may only execute async-signal-safe operations until such time as one of the exec 函数被调用。”这意味着你不应该做
printf("In Child\n");
.