【问题标题】:Segmentation fault when using pthread_join in C在 C 中使用 pthread_join 时出现分段错误
【发布时间】:2016-09-15 03:16:21
【问题描述】:

所以,我正在做一些家庭作业,但我被困在了这个环节。尝试调用 pthread_join 时遇到的错误。

我尝试了不同的解决方案,包括创建一个 void 指针以发送到 pthread_join 调用。

这是我的代码:

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <semaphore.h>
#include <time.h>
#include <pthread.h>

#define NTHREADS 5
#define NVALORES 1000
#define NUMBER_PROCURADO 890

void * run(void *arg);
void fillVector();
int vetor[NVALORES];

int main(){

    int i, vetor2[NTHREADS];
    pthread_t threads[NTHREADS];
    fillVector();
    for (i = 0; i < NTHREADS; i++){
        vetor2[i]=i;
        threads[i]= pthread_create(&threads[i], NULL, run, &vetor2[i]);
    }

    for (i = 0; i < NTHREADS; i++){
        pthread_join(threads[i], NULL);
    }

    return 0;
}

void * run(void * arg){
    int *pos = (int *) arg;

    int i;
    for (i = NVALORES/NTHREADS*(*pos); i < NVALORES/NTHREADS*((*pos)+1); i++){
        if(vetor[i]==NUMBER_PROCURADO){
            printf("Found it! Position: %d\n",i);
        }
        pthread_exit( (void*)pos);
    }
    pthread_exit( (void*)NULL);
}

void fillVector(){
    int i;
    for (i = 0; i < NVALORES; i++){
        vetor[i] = i+1;
    }    
}

【问题讨论】:

  • NVALORES 未定义。
  • 其实已经定义好了,只是这里没有包含。
  • 这可能很重要,如果不是 Fred 回答的真正问题。
  • 我只是说它是定义的,我只是没有将整个代码复制粘贴到这里。无论哪种方式,弗雷德的回答都为我解决了这个问题。还是谢谢。
  • 从技术上讲,这个问题可以作为题外话关闭,因为它不包含MCVE。它不完整,因为(除其他外)NVALORES 未定义。

标签: c pointers segmentation-fault pthreads


【解决方案1】:

您误用了pthread_create 的返回值。它不返回线程 ID。它返回一个错误代码,因此您正在破坏线程 ID 并使您的 pthread_join 调用无效。

【讨论】:

  • 顺便说一句,还有一个问题,在我的朋友计算机上运行 Netbeans 8.1 的 Ubuntu 上,该程序工作正常,它完全是从我在 Geany 1.25 上运行的复制粘贴,这有什么正当理由吗?使用的编译器是 gcc btw。提前致谢。
  • 很可能是未定义的行为。 UB 的一大优点是它包括可以正常工作、段错误或召唤nasal demons
  • @FredLarson 很奇怪,因为在调用pthread_create 时,threads[i] 的断言不能是另一个顺序,不是吗?你认为他们的编译器以不同的顺序做出断言吗?由于代码再次使用数组(为了加入线程),我认为编译器不会有不同的行为。如果他们不使用数组,我认为可以通过不执行断言来解释(因为它不会被使用),这样真的很奇怪。你怎么看?
  • @XavierSilva:我无法理解您的问题,尤其是您对“断言”一词的使用。但我认为正在发生的是使用thread[i] 接收返回值是用pthread_create 返回的错误代码替换线程ID(由pthread_create 通过第一个参数中的指针设置)。然后在pthread_join 中使用此值,导致未定义的行为,因为它不是有效的线程ID。鼻恶魔。
  • 我认为没有理由期望编译器会这样做。 C 的双刃剑是它假设程序员知道他在做什么,并使用该假设来避免大量开销。这导致非常高效的代码和较短的编译时间。当基本假设不正确时,它还会导致许多未定义的行为。
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2017-12-27
  • 2015-05-02
  • 2021-06-13
  • 2013-04-03
相关资源
最近更新 更多