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

标签 c multithreading synchronization pthreads

当我测试子线程之间的 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 real pthread_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()。由于您的每个线程都加入前一个(或至少尝试这样做),因此您只需要主线程加入最后一个。事实上,您不能允许两个不同的线程同时尝试加入同一个线程,因此最后一个线程是主线程应该唯一尝试加入的线程。


修复未定义:

  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;
}

关于c - Pthread_join() 在 C 中返回不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44336728/

相关文章:

java - java中的定时器,时差问题

c - 使用命令行参数声明结构

c# - String to Char* 无内存泄漏

c - 从函数传递字符串

java - 如何每 2 分钟调用一个方法直到它返回 true?

c++ - 编译器内存屏障和互斥量

java - 线程 "Thread-8"java.lang.StackOverflowError...at java.util.Random.nextInt 中出现异常(来源未知)

java - java并发包是用锁实现的吗?

c++ - 如何在不使用信号量的情况下解决寿司吧问题?

c - strtok 未按预期工作,未拆分字符串