pthread_join return 上的段错误
segFault on return from pthread_join
我正在实现一个堆栈池以在特定数量的线程中执行一些基本运算。
代码如下:
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;
}
和结构类型定义:
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,但无法 运行 避免段错误。
这是主要功能的内容:
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
我已经研究了几个小时,尝试了多种方法,尝试了不使用信号量和使用不太有趣的循环,但结果相同。谁能帮我找出问题所在?
您误解了 pthread_join
调用以及模拟 pass-by-reference 的工作原理。
您应该使用 pointer-to 运算符 &
:
传递指向 int *
变量的指针
pthread_join(threads[i], &result);
你还应该记得free
指针result
,否则你会发生内存泄漏。
我正在实现一个堆栈池以在特定数量的线程中执行一些基本运算。
代码如下:
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;
}
和结构类型定义:
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,但无法 运行 避免段错误。 这是主要功能的内容:
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
我已经研究了几个小时,尝试了多种方法,尝试了不使用信号量和使用不太有趣的循环,但结果相同。谁能帮我找出问题所在?
您误解了 pthread_join
调用以及模拟 pass-by-reference 的工作原理。
您应该使用 pointer-to 运算符 &
:
int *
变量的指针
pthread_join(threads[i], &result);
你还应该记得free
指针result
,否则你会发生内存泄漏。