首页 文章

Pthread_join()在C中返回不正确的值

提问于
浏览
0

当我在子线程之间测试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 回答

  • 3

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

    ......因此,你似乎为自己造成了更严重的问题 . 至少,我通过向每个线程传递一个指向 thread_create() 的局部变量 input 的指针来解释你的意图避免共享变量,但是,正如在注释中观察到的那样,只要 thread_create() 返回,指针就会在启动后立即变为无效新线程 . 当线程此后取消引用那些指针 - 它们会多次执行 - 它们会产生未定义的行为 .

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

    程序的行为是未定义的,因此返回值可能不是您想要或期望的可靠,但没有判断它们是否正确的依据 .

    问题2:主线程如何等待其他线程完成?(我不确定,所以我使用while(1)来确保所有线程完成 . )

    一个线程等待另一个线程完成的方法是调用 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;
    }
    

相关问题