使用pthread_create进行分段错误

时间:2018-05-20 23:18:36

标签: c segmentation-fault pthreads mutex

我尝试理解C中的pthread和互斥。我想要编写一个程序,它计算给定值的平方并将其存储在给定大小的数组中。我想创建4个pthreads来计算每个值,然后存储它们。所以我希望得到以下结果:[25] [25] ... [25],x = 5,a = 10(数组大小)。 到目前为止我的代码是:

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

#define NTHREADS 4
static int k = 0;

struct thread_info{
    pthread_t thread_id;
    pthread_mutex_t lock;
    int x;
    int a[10];
};

void* fkt(void* arg){
    struct thread_info* tinfo = (struct thread_info*) arg;

    if(pthread_mutex_lock(&tinfo->lock)) perror("mutex_lock");

    printf("THREAD %d with argument %d\n", (int) tinfo->thread_id, tinfo->x);

    tinfo->a[k] = tinfo->x * tinfo->x;
    k++;

    if(pthread_mutex_unlock(&tinfo->lock)) perror("mutex_unlock");

    pthread_exit(NULL);
}

int main(){
    struct thread_info* tinfo = (struct thread_info*) malloc(sizeof(struct thread_info));

    tinfo->x = 5;

    if(pthread_mutex_init(&tinfo->lock, NULL)) perror("mutex_init");

    for(int i = 0; i < NTHREADS; i++){
        if(pthread_create(&tinfo[i].thread_id, NULL, &fkt, &tinfo)) perror("pthread_create");
    }   
    for(int i = 0; i < NTHREADS; i++){
        if(pthread_join(tinfo[i].thread_id, NULL)) perror("pthread_join");
        printf("THREAD JOINED: %d\n", (int) tinfo->thread_id);
    }   
    for(int i = 0; i < 10; i++){
        printf("[%d]\t", tinfo->a[i]);
    }   
    printf("\n");

    if(pthread_mutex_destroy(&tinfo->lock)) perror("mutex_destroy");

    return 0;
}

不幸的是我遇到了分段错误,我不明白为什么。 Valgrind说“4号写入无效”这句话是什么意思?

编辑:我从main函数中的tinfo声明中删除了NULL。仍然使用valgrind获得分段错误。执行二进制文件似乎无限运行。

2 个答案:

答案 0 :(得分:2)

  

不幸的是我遇到了分段错误,我不明白为什么。

不难看出原因:程序开头的这两行保证了它:

struct thread_info* tinfo = NULL;
tinfo->x = 5;

第二行尝试写入(取消引用)在第一行创建的NULL指针。

你应该学习使用调试器,这样你就不会被这些琐碎的错误所困扰。

(你的程序中可能还有其他错误,我没看。)

<强>更新

现在您已经纠正了第一个问题,但引入了一个新问题:此行为一个 thread_info分配空间:

struct thread_info* tinfo =
  (struct thread_info*) malloc(sizeof(struct thread_info));

但是这一行溢出了i以上0的所有值的缓冲区:

for(int i = 0; i < NTHREADS; i++){
    if(pthread_create(&tinfo[i].thread_id, ...

答案 1 :(得分:1)

我认为在调用pthread_create时,您可能也错误地传递了指向线程目标函数参数的指针。由于tinfo函数中的变量mallocmain'd,因此它已经是指针。但是,当您将目标函数的参数传递给pthread_create时,您会传入&tinfo,它实际上具有struct thread_info **类型。也就是说,它不是指向struct thread_info的指针,而是一个可以解除引用一次以获得指向struct thread_info的指针。这会导致问题,因为fkt将此指针视为struct thread_info *,这是不正确的。我敢打赌,在致电&tinfo时,只用tinfo替换pthread_create将有助于解决问题。