从 pthread_join 返回时出现 segFault

发布于 2025-01-17 10:11:46 字数 3284 浏览 0 评论 0原文

我正在实现一个堆栈池,以在特定数量的线程中进行一些基本的算术。

这是代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回忆那么伤 2025-01-24 10:11:46

您误解了 pthread_join 调用以及模拟按引用传递的工作原理。

您应该使用指针运算符 & 将指针传递给 int * 变量:

pthread_join(threads[i], &result);

您还应该记住释放指针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 &:

pthread_join(threads[i], &result);

You should also remember to free the pointer result, or you will have a memory leak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文