乙
基本上主线程创建了 4 个线程 1 ,2 ,3 ,4 和 1、2、3 必须等待 4 结束,而 main 等待线程 1 2 3。 代码如下:
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t id[4];
void *func1(void *arg)
{
printf("i am the %ith thread\n",(int)arg);
pthread_join(id[3],NULL);
printf("end of %ith thread\n",(int)arg);
pthread_exit(NULL);
}
void *func2(void *arg)
{
printf("i am the 4th thread\n");
sleep(5);
printf("end of 4th thread\n");
pthread_exit(NULL);
}
int main()
{
printf("start of main thread\n");
pthread_create(&id[3],NULL,func2,NULL);
for(int i=0;i<3;i++)
{
pthread_create(&id[i],NULL,func1,(void *)i);
}
for(int i=0;i<3;i++)
{
pthread_join(id[i],NULL);
}
printf("end of main\n");
return 0;
}
跑步时我得到这样的东西:` 主线程开始 我是第0个线程 我是第 4 个线程 我是第二个线程 我是第一个线程 4线程结束 第0个线程结束
请原谅这些可怕的信息,因为我匆忙将它们从法语翻译过来。 理论上线程 1 2 3 应该等待 4 然后自己完成,但每次尝试只有一个线程在 4 之后完成,然后整个执行被无限期地阻塞。 我尝试确保第 4 个线程总是首先从 pthread_attr_t 开始,并设置第 4 个高的调度优先级,但不幸的是,这没有用。 我尝试查找有关 pthread_join 的一些详细信息,如果将多个线程加入一个线程是不安全的或不允许的,但我没有找到任何建议。 任何帮助将不胜感激提前谢谢你。
来自
pthread_join()
手册页:
如果多个线程同时尝试加入同一个线程,结果是不确定的。
如果需要在多个线程中等待线程终止,创建相应的标志包装到条件变量。在退出之前终止线程或在另一个线程中加入线程后广播条件变量。
补充说明:
pthread_exit(NULL)
在线程函数的末尾是多余的。只需返回 NULL。int
到 void*
的转换可能会溢出,编译器不喜欢这样。我们可以使用 intptr_t
代替 int
但是在 intptr_t
中没有 printf()
的转换说明符,因此我们无论如何都应该转换。我们可以使用 intptr_t
的中间转换来让编译器开心。程序可能是这样的:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
static pthread_t id[4];
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static int terminated = 0;
static void *func1(void *arg)
{
printf("i am the %ith thread\n",(int)(intptr_t)arg);
// Wait until 4th thread termination flag is set
pthread_mutex_lock(&mtx);
while (!terminated) {
pthread_cond_wait(&cond, &mtx);
}
pthread_mutex_unlock(&mtx);
printf("end of %ith thread\n",(int)(intptr_t)arg);
return NULL;
}
static void *func2(void *)
{
printf("i am the 4th thread\n");
sleep(5);
printf("end of 4th thread\n");
// Set termination flag and broadcast state change
pthread_mutex_lock(&mtx);
terminated = 1;
pthread_mutex_unlock(&mtx);
pthread_cond_broadcast(&cond);
return NULL;
}
int main()
{
printf("start of main thread\n");
int ret;
ret = pthread_create(&id[3],NULL,func2,NULL);
if (ret) {
fprintf(stderr, "pthread_create(id[3]): %s\n", strerror(ret));
return 1;
}
for(int i=0;i<3;i++)
{
ret = pthread_create(&id[i],NULL,func1,(void *)(intptr_t)i);
if (ret) {
fprintf(stderr, "pthread_create(id[%i]): %s\n", i, strerror(ret));
return 1;
}
}
// Wait for all 4 threads
for(int i=0;i<4;i++)
{
int ret = pthread_join(id[i],NULL);
if (ret != 0) {
fprintf(stderr, "pthread_join(id[%i]): %s\n", i, strerror(ret));
}
}
printf("end of main\n");
return 0;
}
UPD:有更简单的方法:将
pthread_join()
调用包装到由互斥锁保护的临界区:
static pthread_t id[4];
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
static int terminated = 0;
static void *func1(void *arg)
{
printf("i am the %ith thread\n",(int)(intptr_t)arg);
// Wait until 4th thread termination flag is set
pthread_mutex_lock(&mtx);
if (!terminated) {
int ret = pthread_join(id[3],NULL);
if (ret != 0) {
fprintf(stderr, "pthread_join(id[3]): %s\n", strerror(ret));
}
terminated = 1;
}
pthread_mutex_unlock(&mtx);
printf("end of %ith thread\n",(int)(intptr_t)arg);
return NULL;
}
static void *func2(void *)
{
printf("i am the 4th thread\n");
sleep(5);
printf("end of 4th thread\n");
return NULL;
}
在这种情况下,您不需要在
main()
中加入第4个线程:
for(int i=0;i<3;i++) {
int ret = pthread_join(id[i],NULL);
...