2017-06-02 52 views
0

返回不正确的值与pthreads玩的时候我遇到了一个问题,当我测试的子线程之间的在pthread_join()。我试图避免共享变量,所以我用另一个thread_create()函数来执行真实在pthread_create()在pthread_join(c)中

为了跟踪线程,我创建了一个pthread_t数组tid [N]来存储线程,并且索引也会根据数组中的索引附加到每个线程。

但是,输出示出了一些螺纹具有相同的索引。 我想变量索引必须以某种方式共享。索引被转移为实际参数到thread_create()和结构变量输入假定的thread_create()函数完成之后被清除。我不太明白为什么索引会在子线程之间共享。 有没有人可以解释这一点?提前致谢!!

总之

问题1:为什么返回值是不正确的?

问题2:怎样主线程等待其他线程完成(我不知道,所以我用了一段时间(1),以确保所有的线程完成。)

?一个注释:如果我们取消注释第38行中的睡眠(),程序会给出正确的输出。

以下均代码:

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 } 
+2

''中混合thread_create' input'超出范围的函数返回后,但线程仍在访问它。 – mch

+0

'thread_talk'中的'input-> tid [index-1]'是错误的,它应该只是'input-> tid'。 – zwol

+0

'(void *)(&input)'在线程获得'input'的地址时,input已经*>不见了*。 – ThingyWotsit

回答

3

我试图避免共享变量,所以我用另一个thread_create()函数来执行真实pthread_create()

...因此,您似乎已经为自己创造了更糟糕的问题。至少,我理解你的意图,以避免共享变量的指针传递每个线程thread_create()的局部变量input实现,但正如评论已经指出,该指针便具有thread_create()回报无效,启动后立即新的线程。当线程解除引用这些指针时 - 它们会多次执行 - 会产生未定义的行为。

问题1:为什么返回值不正确?

程序的行为是不确定的,所以返回值可能不可靠的是你想要的或期望的,但对于判断它们是否正确没有基础。

问题2:如何做的主要工作线程等待其他线程完成(我不知道,所以我用了一段时间(1),以确保所有的线程完成?)

一个线程等待另一个线程完成的方法是调用pthread_join()。由于你的每个线程都加入了前一个线程(或者至少尝试这样做),所以你只需要主线程加入最后一个线程。事实上,你不能让两个不同的线程同时尝试加入同一个线程,所以最后一个线程是主线程应该尝试加入的唯一线程。


杀青undefinedness:

  1. 摆脱thread_create()。它只是混淆了这个问题。

  2. 你有两个选择:

    1. 在主线程创建多个mix对象 - 例如他们的数组 - 并交给每个线程不同的一个。
    2. 在主线程中使用一个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; 
}