使用一个参数调用 pthread_join 会导致分段错误?

Posted

技术标签:

【中文标题】使用一个参数调用 pthread_join 会导致分段错误?【英文标题】:Calling pthread_join with one argument causes a segmentation fault? 【发布时间】:2021-05-11 02:06:00 【问题描述】:

如果我连续调用 pthread_join(不使用其他函数)会导致分段错误。

我可以通过在两次 pthread_join 调用之间插入 sleep();printf() 或其他任何内容来解决问题。

操作系统和 GCC 版本:

gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

编译命令:

gcc demo_thread.c -lpthread  -o demo_thread.out

源码(demo_thread.c):

#include <stdio.h>
#include <stdlib.h>

void *f1(void *);

int main() 
    int k = 2;
    pthread_t fa[k];
    for(int i=0; i<k; i++) 
        pthread_create(&fa[i], NULL, f1, NULL);  
    

    for(int i=0; i<k; i++) 
        // printf("%ul\n", fa[i]); // uncomment this line, problem disapper.
        pthread_join(fa[i]);
    


void *f1(void *arg) 
    for(int i=0; i<4;i++) 
        printf("%d\n",i );
    
    return 0;

【问题讨论】:

始终检查您的错误返回。如果pthread_create 失败,它不会将您的fa[i] 设置为任何有效值。我想您必须将k 设置得非常高,因为只要 k = 2,这里就没有问题。 我只设置了 k = 2。我可以确保调用 pthread_create 成功。 【参考方案1】:

你是怎么编译的?我刚刚意识到您没有使用#include &lt;pthread.h&gt;,并且您使用了一个参数而不是两个pthread_join

如果我遗漏了我得到的包含

error: unknown type name ‘pthread_t’

如果我确实包含它,那么我会得到

error: too few arguments to function ‘pthread_join’

哦,我知道如果我包含#include &lt;stdlib.h&gt; 并省略&lt;pthread.h&gt;,那么它将有一个pthread_t 的定义,但没有pthread_join 的定义。但是仍然有很多警告:

warning: implicit declaration of function ‘pthread_join’

您应该始终使用编译器的-Wall -W -pedantic 参数构建程序。并修复警告。

并解释崩溃:由于您没有将 NULL 作为第二个参数传递给pthread_join,它将接收一个“随机”值,然后将其写入它,就好像它是一个指针一样。它不是。所以它要么将一个值写入你不应该分配的内存中,要么会出现分段错误。

并解释printfsleep 如何解决问题:进行这些函数调用必须更改RSI 寄存器的值(RSI 用于第二个函数参数),使其成为有效指针或 NULL。

【讨论】:

我编译代码的方式是gcc -g demo_thread.c -lpthread -o demo_thread.out。也许你错过了-lpthread @omar.zhou 不,我没有错过。我的编辑器和 Makefile 中有很多自动化的东西,所以起初我什至没有看到标题丢失,因为我的编辑器自动添加了它,并删除了 stdlib.h,因为它从未使用过。并且-pthread 会自动添加到编译器标志中。

以上是关于使用一个参数调用 pthread_join 会导致分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

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

等待 pthread_create 完成而不使用 pthread_join

SylixOS pthread_join退出

c - 无法理解 pthread_join()

线程分离

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