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,否则你会发生内存泄漏。