从 pthread_join 返回时出现 segFault
我正在实现一个堆栈池,以在特定数量的线程中进行一些基本的算术。
这是代码:
int add(int a, int b) {return a+b;}
int sub(int a, int b) {return a-b;}
int mul(int a, int b) {return a*b;}
sem_t sem_ops;
void* compute(void* arg){
Args *args = arg;
Operation* op = args->operation;
printOP(*op);
int * value = malloc ( sizeof ( int ) ) ;
* value = op->op(op->a, op->b);
args->is_complete = true;
sem_post(&sem_ops);
return value;
}
void push(Operation op , Queue* q){
q->operations[++(q->last)] = op;
}
Operation *pop(Queue *q){
q->first++;
return &q->operations[q->first];
}
int size(Queue *q){
return q->last - q->first;
}
bool read_operations(char* filename, Queue* ops){
printf("reading from file %s\n",filename);
FILE *fp = fopen(filename, "r");
if(fp == NULL )
{
printf("couldnt open");
return false;
}
int id,a,b;
while(!feof(fp)){
fscanf(fp,"%d %d %d\n",&id,&a,&b);
Operation op;
op.a = a;
op.b = b;
switch (id){
case 0:
op.op = add;
break;
case 1:
op.op = sub;
break;
case 2:
default:
op.op =mul;
break;
}
push(op,ops);
}
return true;
}
ArrayList* execute_thread_pool(char* filename, int poolSize){
sem_init(&sem_ops,0,poolSize);
//init return value
ArrayList* retval =malloc(sizeof(ArrayList));
int res [ TOTAL_OP_COUNT];
retval->results = res;
retval->count = 0;
// populate Q
Queue q;
Operation ops[TOTAL_OP_COUNT];
q.first = 0;
q.last = 0;
q.max = TOTAL_OP_COUNT;
q.operations = ops;
read_operations(filename,&q);
// thread tids
pthread_t threads[TOTAL_OP_COUNT];
//args for each thread
Args args[TOTAL_OP_COUNT];
int* result= NULL;
for(int i =0; i<poolSize; ++i){
sem_wait(&sem_ops);
args[i].operation = pop(&q);
args[i].is_complete=false;
pthread_create(&threads[i],NULL, compute,&args[i]);
}
for(int i =0; i<poolSize; ++i){
if(args[i].is_complete){
pthread_join(threads[i],(void**) result);
res[i] = *result; // line 88
}else --i;
}
return retval;
}
和structs typedefs:
typedef struct _Operation{
int(*op) (int, int);
int a;
int b;
} Operation;
typedef struct _Args{
Operation* operation;
bool is_complete;
}Args;
typedef struct _Queue{
Operation* operations;
int last;
int first;
int max;
}Queue;
我尝试在几个不同的地方使用malloc,但不能逃离segfault。 这是主要功能的内容:
ArrayList *al =malloc(sizeof(ArrayList)) ;
al = execute_thread_pool("bob.txt", 4);
在GDB中,BT如下:
#0 0x0000555555555762 in execute_thread_pool (filename=0x555555556004 "bob.txt", poolSize=4) at pool.c:88
#1 0x00005555555552db in main (argc=1, argv=0x7fffffffda68) at main.c:5
我已经使用了几个小时,尝试了多种方法,尝试了没有信号量,并且使用不那么有趣的循环,但结果也相同。谁能帮我发现这个问题?
I am implementing a stack pool to do some basic arithmetic in a specific number of threads.
here is the code:
int add(int a, int b) {return a+b;}
int sub(int a, int b) {return a-b;}
int mul(int a, int b) {return a*b;}
sem_t sem_ops;
void* compute(void* arg){
Args *args = arg;
Operation* op = args->operation;
printOP(*op);
int * value = malloc ( sizeof ( int ) ) ;
* value = op->op(op->a, op->b);
args->is_complete = true;
sem_post(&sem_ops);
return value;
}
void push(Operation op , Queue* q){
q->operations[++(q->last)] = op;
}
Operation *pop(Queue *q){
q->first++;
return &q->operations[q->first];
}
int size(Queue *q){
return q->last - q->first;
}
bool read_operations(char* filename, Queue* ops){
printf("reading from file %s\n",filename);
FILE *fp = fopen(filename, "r");
if(fp == NULL )
{
printf("couldnt open");
return false;
}
int id,a,b;
while(!feof(fp)){
fscanf(fp,"%d %d %d\n",&id,&a,&b);
Operation op;
op.a = a;
op.b = b;
switch (id){
case 0:
op.op = add;
break;
case 1:
op.op = sub;
break;
case 2:
default:
op.op =mul;
break;
}
push(op,ops);
}
return true;
}
ArrayList* execute_thread_pool(char* filename, int poolSize){
sem_init(&sem_ops,0,poolSize);
//init return value
ArrayList* retval =malloc(sizeof(ArrayList));
int res [ TOTAL_OP_COUNT];
retval->results = res;
retval->count = 0;
// populate Q
Queue q;
Operation ops[TOTAL_OP_COUNT];
q.first = 0;
q.last = 0;
q.max = TOTAL_OP_COUNT;
q.operations = ops;
read_operations(filename,&q);
// thread tids
pthread_t threads[TOTAL_OP_COUNT];
//args for each thread
Args args[TOTAL_OP_COUNT];
int* result= NULL;
for(int i =0; i<poolSize; ++i){
sem_wait(&sem_ops);
args[i].operation = pop(&q);
args[i].is_complete=false;
pthread_create(&threads[i],NULL, compute,&args[i]);
}
for(int i =0; i<poolSize; ++i){
if(args[i].is_complete){
pthread_join(threads[i],(void**) result);
res[i] = *result; // line 88
}else --i;
}
return retval;
}
and the structs typedefs:
typedef struct _Operation{
int(*op) (int, int);
int a;
int b;
} Operation;
typedef struct _Args{
Operation* operation;
bool is_complete;
}Args;
typedef struct _Queue{
Operation* operations;
int last;
int first;
int max;
}Queue;
I tried using malloc at a few different places, but can't run away from segfault.
this is the content of the main function:
ArrayList *al =malloc(sizeof(ArrayList)) ;
al = execute_thread_pool("bob.txt", 4);
in gdb the bt is as follow:
#0 0x0000555555555762 in execute_thread_pool (filename=0x555555556004 "bob.txt", poolSize=4) at pool.c:88
#1 0x00005555555552db in main (argc=1, argv=0x7fffffffda68) at main.c:5
I've been on this for a few hours, tried multiple ways, tried without semaphores and using not so fun loops and yet the same result. can anyone help me spot the issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您误解了 pthread_join 调用以及模拟按引用传递的工作原理。
您应该使用指针运算符
&
将指针传递给int *
变量:您还应该记住
释放
指针result
,否则会出现内存泄漏。You misunderstand the
pthread_join
call and how emulating pass-by-reference work in works.You are supposed to pass a pointer to an
int *
variable, using the pointer-to operator&
:You should also remember to
free
the pointerresult
, or you will have a memory leak.