我尝试理解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获得分段错误。执行二进制文件似乎无限运行。
答案 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
函数中的变量malloc
为main
'd,因此它已经是指针。但是,当您将目标函数的参数传递给pthread_create
时,您会传入&tinfo
,它实际上具有struct thread_info **
类型。也就是说,它不是指向struct thread_info
的指针,而是一个可以解除引用一次以获得指向struct thread_info
的指针。这会导致问题,因为fkt
将此指针视为struct thread_info *
,这是不正确的。我敢打赌,在致电&tinfo
时,只用tinfo
替换pthread_create
将有助于解决问题。