pthread_create 的分段错误
Segmentation fault with pthread_create
我试图理解 C 中的 pthread 和 mutex。我想要两个人编写一个程序,计算给定值的平方并将其存储在给定大小的数组中。我想创建 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 说 "Invalid write of size 4" 那句话是什么意思?
编辑:我从主函数的 tinfo 声明中删除了 NULL。仍然遇到 valgrind 的分段错误。执行二进制文件似乎 运行 无限。
Unfortunately I get a segmentation fault and I dont see why.
不难看出原因:程序开头的这两行保证了这一点:
struct thread_info* tinfo = NULL;
tinfo->x = 5;
第二行尝试写入(取消引用)在第一行创建的 NULL
指针。
你应该学会使用调试器,这样你就不会被这些微不足道的错误难倒了。
(你的程序可能还有其他bug,我没看。)
更新:
现在您已经纠正了第一个问题,但引入了一个新问题:此行分配 space 给 one thread_info
:
struct thread_info* tinfo =
(struct thread_info*) malloc(sizeof(struct thread_info));
但是对于 0
以上 i
的所有值,此行溢出该缓冲区:
for(int i = 0; i < NTHREADS; i++){
if(pthread_create(&tinfo[i].thread_id, ...
我认为您在调用 pthread_create
时可能还错误地传递了指向线程目标函数参数的指针。由于变量 tinfo
在您的 main
函数中是 malloc
,它已经是一个指针。但是,当您将目标函数的参数传递给 pthread_create
时,您传递的是 &tinfo
,它的类型实际上是 struct thread_info **
。也就是说,它不是指向 struct thread_info
的指针,而是可以取消引用一次以获得指向 struct thread_info
的指针的指针。这会导致问题,因为 fkt
将此指针视为 struct thread_info *
,这是不正确的。我敢打赌,在您对 pthread_create
的调用中将 &tinfo
替换为 tinfo
将有助于解决问题。
我试图理解 C 中的 pthread 和 mutex。我想要两个人编写一个程序,计算给定值的平方并将其存储在给定大小的数组中。我想创建 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 说 "Invalid write of size 4" 那句话是什么意思?
编辑:我从主函数的 tinfo 声明中删除了 NULL。仍然遇到 valgrind 的分段错误。执行二进制文件似乎 运行 无限。
Unfortunately I get a segmentation fault and I dont see why.
不难看出原因:程序开头的这两行保证了这一点:
struct thread_info* tinfo = NULL;
tinfo->x = 5;
第二行尝试写入(取消引用)在第一行创建的 NULL
指针。
你应该学会使用调试器,这样你就不会被这些微不足道的错误难倒了。
(你的程序可能还有其他bug,我没看。)
更新:
现在您已经纠正了第一个问题,但引入了一个新问题:此行分配 space 给 one thread_info
:
struct thread_info* tinfo =
(struct thread_info*) malloc(sizeof(struct thread_info));
但是对于 0
以上 i
的所有值,此行溢出该缓冲区:
for(int i = 0; i < NTHREADS; i++){
if(pthread_create(&tinfo[i].thread_id, ...
我认为您在调用 pthread_create
时可能还错误地传递了指向线程目标函数参数的指针。由于变量 tinfo
在您的 main
函数中是 malloc
,它已经是一个指针。但是,当您将目标函数的参数传递给 pthread_create
时,您传递的是 &tinfo
,它的类型实际上是 struct thread_info **
。也就是说,它不是指向 struct thread_info
的指针,而是可以取消引用一次以获得指向 struct thread_info
的指针的指针。这会导致问题,因为 fkt
将此指针视为 struct thread_info *
,这是不正确的。我敢打赌,在您对 pthread_create
的调用中将 &tinfo
替换为 tinfo
将有助于解决问题。