当我在子线程之间测试pthread_join()时,我在使用Pthreads时遇到了问题 . 我试图避免共享变量,所以我使用另一个 thread_create() 函数来执行真正的 pthread_create() .
为了跟踪线程,我创建了一个pthread_t数组 tid[N] 来存储线程,并且还根据数组中的索引将索引附加到每个线程 .
但是,输出显示某些线程具有相同的索引 . I guess the variable index must be shared 不知何故 . 索引作为实际参数传递给thread_create(),并且在thread_create()函数完成后应该清除struct变量 input . 我不太明白为什么索引在子线程之间共享 . 有没有人可以解释这个?提前致谢!!
To summarize ,
Question 1: 为什么返回值不正确?
Question 2: 主线程如何等待其他线程完成?(我不确定,所以我使用while(1)来确保所有线程完成 . )
One note :如果我们在第38行取消注释sleep(),程序会给出正确的输出 .
以下是代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <pthread.h>
4 #include <syscall.h>
5
6 #define N 4
7
8 typedef struct{
9
10 int index;
11 pthread_t *tid;
12
13 }mix;
14
15 void* thread_talk(mix* input)
16 {
17 int* ret;
18 int index = input->index;
19 printf("In process %d, thread %u running, my index is %d\n",
20 getpid(), pthread_self(), index);
21
22 /*thread 0 won't join*/
23 if(input->index == 0){
24 printf("thread 0 will stop\n");
25 return (void*)0;
26 }
27 /*Join the thread based on the index of tid*/
28 pthread_join(input->tid[index - 1], &ret);
29 printf("My index is %d, I receive the return value %d\n",index, ret);
30 return (void*)(input->index);
31 }
32
33 int thread_create(pthread_t* tid, int index)
34 {
35 mix input = {index, tid};
36 printf("my index is %d\n");
37 pthread_create(&tid[index], NULL, thread_talk, (void*)(&input));
38 //sleep(1);
39 return 0;
40 }
41
42 int main()
43 {
44
45 pthread_t tid[N];
46 int i;
47 for(i = 0; i < N; i++)
48 thread_create(tid,i);
49 while(1);
50 return 0;
51 }
1 回答
......因此,你似乎为自己造成了更严重的问题 . 至少,我通过向每个线程传递一个指向
thread_create()
的局部变量input
的指针来解释你的意图避免共享变量,但是,正如在注释中观察到的那样,只要thread_create()
返回,指针就会在启动后立即变为无效新线程 . 当线程此后取消引用那些指针 - 它们会多次执行 - 它们会产生未定义的行为 .程序的行为是未定义的,因此返回值可能不是您想要或期望的可靠,但没有判断它们是否正确的依据 .
一个线程等待另一个线程完成的方法是调用
pthread_join()
. 由于每个线程都加入了前一个线程(或者至少尝试这样做),因此只需要主线程加入最后一个线程 . 实际上,您不能允许两个不同的线程同时尝试加入同一个线程,因此最后一个线程是主线程应该尝试加入的唯一线程 .修复不确定性:
摆脱
thread_create()
. 它只是混淆了这个问题 .您有两种选择:
在主线程中创建多个
mix
对象 - 例如他们的数组 - 并为每个线程交出不同的一个 .在主线程中使用一个
mix
对象,将其传递给每个子对象,并让子线程进行内部复制 . 此备选方案需要主线程和子线程之间的同步,以便主线程在新子进程复制之前不会继续 .我会使用数组,因为它更容易正确实现: