c - 无法理解 pthread_join()

Posted

技术标签:

【中文标题】c - 无法理解 pthread_join()【英文标题】:c - can't understand pthread_join() 【发布时间】:2019-01-22 15:04:37 【问题描述】:

我不知道我错在哪里,在运行代码到达它运行 pthread_join() 的位置后,许多 pthread_join() 返回值 3 而不是 0。此外,打印 @987654324 的值@ 并不总是一致的,这会导致分段错误并在同一位置打印多次。 在 cmets 中按要求修改代码 所有包含的内容都适用于程序的其他部分。仅测试这段代码会在 pthread_join() 上的错误 3 处产生分段错误

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>

#include <errno.h>
#include <config.h>
#include <sys/select.h>
#include <ctype.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <sys/un.h>

void *threadF()
    printf("hello\n");
    pthread_exit((void*)0);     





int main(int argc, char *argv[]) 

    FILE *fileconf=fopen(argv[2],"r"); 
    if(fileconf==NULL)
        fprintf(stderr, "Fopen\n",argv[2]);
        return -1;
    
    set_conf(fileconf); //parse fileconf and set THREADSINPOOL correctly

    pthread_t array[THREADSINPOOL];
    int i,err,s=0;
    for(i=0;i<THREADSINPOOL;i++)
        if((err=pthread_create(&array[i],NULL,&threadF,NULL))!=0)
            fprintf(stderr,"thread\n");
            exit(errno);
        
    

    int tmp;

    for(i=0;i<THREADSINPOOL;i++)
        tmp=pthread_join(array[i],(void *)&s);
        printf("thread: %lu terminated\n tmp: %d\n",array[i],tmp);
    

    return 0;

【问题讨论】:

需要minimal reproducible example。您描述的症状表明某种未定义的行为。如果没有完整的代码集(我的意思是一组可以编译和运行的代码,但要尽可能短),我们将无法看到这一点。 首先要了解3 的含义。这就是man 页面的作用所在。 代码已编辑,这个简单的代码会导致段错误 您的 printf() 格式需要两个值,但您只传递了 1,这会导致未定义的行为并且所有赌注都关闭...如果您的编译器没有警告您,请记住始终在 gcc 和 clang 上至少使用 -Wall -Wextra 进行编译。 pthread_join 正在使用 void ** 而不是 void *。显然int s 可能没有空间容纳void* 【参考方案1】:

问题是您将int 的地址传递给需要void * 地址的函数。在 64 位系统上,int 很有可能只有 32 位,而 void * 很可能是 64 位。所以pthread_join 最终将 64 位写入一个仅足够容纳 32 位的位置。结果是您覆盖了不应更改的内存,并且随之而来的是各种未定义的行为。

这是一种编写代码的方法,以便pthread_join 的第二个参数实际上是指向void * 的指针

for (i = 0; i < THREADSINPOOL; i++)

    void *value;
    if (pthread_join(array[i], &value) == 0)
        printf("thread %d returned %" PRIiPTR "\n", i, (intptr_t)value);
    else
        printf("thread %d failed\n", i);

【讨论】:

如果您不使用 printf 打印值,则此代码有效 >从指针转换为不同大小的整数 [-Werror=pointer-to-int-cast] printf("thread %d returned %d\n", i, (int)value);

以上是关于c - 无法理解 pthread_join()的主要内容,如果未能解决你的问题,请参考以下文章

C语言 pthread_join()函数

C语言 pthread_join()函数

如何在C中使用pthread_join来控制线程数?

在可能尚未创建的pthread_t上调用pthread_join

如何停止在共享库中实现的阻塞 pthread_join()

调用 pthread_join() 两次时 glibc pthread_join 崩溃