当我测试子线程之间的 pthread_join() 时,我在使用 Pthreads 时遇到了一个问题。我试图避免共享变量,所以我使用另一个 thread_create() 函数来执行真正的 pthread_create()。
为了跟踪线程,我创建了一个 pthread_t 数组 tid[N] 来存储线程,并且还根据数组中的索引为每个线程附加了一个索引。
但是,输出显示某些线程具有相同的索引。 我想变量索引必须以某种方式共享。索引作为实际参数传输到 thread_create() 中,结构变量 input 应该在 thread_create() 函数完成后被清除。我不太明白为什么索引在子线程之间共享。 有没有人可以解释这个?提前致谢!!
总结,
问题1:为什么返回值不正确?
问题 2: 主线程如何等待其他线程完成?(我不确定,所以我使用 while(1) 来确保所有线程完成。)
注意:如果我们在第 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 }
最佳答案
I tried to avoid the shared variables, so I use another
thread_create()
function to perform the realpthread_create()
.
...因此你似乎给自己制造了一个更糟糕的问题。至少,我解释了您通过向每个线程传递指向 thread_create()
的局部变量 input
的指针来避免共享变量的意图,但是,正如所观察到的在注释中,该指针在 thread_create()
返回后立即失效,在新线程启动后立即生效。当线程此后取消对这些指针的引用时(它们多次这样做),它们会产生未定义的行为。
Question 1: why the return value are not correct?
程序的行为是未定义的,因此返回值可能不是您想要或期望的可靠值,但没有判断它们是否正确的依据。
Question 2: How does the main threads wait for the other threads to complete?(I am not sure, so I use the while(1) to make sure all the threads completes.)
一个线程等待另一个线程完成的方法是调用pthread_join()
。由于您的每个线程都加入前一个(或至少尝试这样做),因此您只需要主线程加入最后一个。事实上,您不能允许两个不同的线程同时尝试加入同一个线程,因此最后一个线程是主线程应该唯一尝试加入的线程。
修复未定义:
摆脱
thread_create()
。这只会让事情变得困惑。你有两个选择:
- 在主线程中创建多个
mix
对象——例如它们的数组 - 并向每个线程传递不同的一个。 - 在主线程中使用一个
mix
对象,将其传递给每个子线程,并让子线程制作内部副本。此替代方案需要主线程和子线程之间的同步,以便主线程在新子线程完成其副本之前不会继续。
- 在主线程中创建多个
我会选择数组,因为它更容易正确实现:
// ...
int main() {
pthread_t tid[N];
mix input[N];
int i;
for (i = 0; i < N; i++) {
input[i].index = i;
input[i].tid = tid;
pthread_create(&tid[index], NULL, thread_talk, (void*)(input + i));
}
pthread_join(tid[N - 1], NULL);
return 0;
}
关于c - Pthread_join() 在 C 中返回不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44336728/