c - 段错误加入线程号 5 (pthread_join)

标签 c multithreading segmentation-fault pthread-join

我正在尝试解决一个小的同步问题。但是当我加入线程时,我得到了第五次迭代的段错误!如果我只创建 4 个线程就完美了。

在这里,我留下了一些关于如何处理线程的基础知识的代码。

#include <stdio.h>              
#include <stdlib.h>             
#include <string.h>             
#include <pthread.h>            
#include <semaphore.h>

sem_t HackersEmploy_Counter;
int hackerOnBoat, employOnBoat, B, b, hackerResagado, employResagado;

sem_t Board;
int onBoatId[4];     
char onBoatType[4]; 

sem_t Bote;  

typedef struct{
    FILE* log;
    int ID;
}param;

void* HackerArrive(void* para){
    param* var = (param*) para;
    printf("Create Hacker %i\n", var->ID-1);
    pthread_exit(0);
}

void* EmployeeArrive(void* para){
    param* var = (param*) para;
    printf("Create Employee %i\n", var->ID-1);
    pthread_exit(0);
}

int main(int argc, char **argv) {
    sem_init(&HackersEmploy_Counter,0,1);
    sem_init(&Bote,0,4);
    sem_init(&Board,0,1);
    FILE* log;
    log = fopen("result_simulacion.txt", "w");
    int E, e=1, H, h=1, i, r;
    hackerOnBoat=0; employOnBoat=0; b=1; hackerResagado=0; employResagado=0;
    for (i=1; i<argc; i++){
        if (strcmp(argv[i],"-h")==0){
            i++;
            H = atoi(argv[i]);
        }
        if (strcmp(argv[i],"-e")==0){
            i++;
            E = atoi(argv[i]);
        }
        if (strcmp(argv[i],"-b")==0){
            i++;
            B = atoi(argv[i]);
        }
    }
    pthread_t* bank = (pthread_t*) malloc( (E+H) * sizeof (pthread_t*));
    param* var = (param*) malloc( (E+H) + sizeof (param*));
    for (i=0; i<H+E; i++){
        r = rand() % 2;
        if (r==0){
            if (h<=H){
                var[i].log = log;
                var[i].ID = h;
                pthread_create(&bank[i], NULL, HackerArrive, (void*) &var[i]);
                h++;
            }else{
                var[i].log = log;
                var[i].ID = e;
                pthread_create(&bank[i], NULL, EmployeeArrive, (void*) &var[i]);
                e++;
            }
        }else{
            if (e<=E){
                var[i].log = log;
                var[i].ID = e;
                pthread_create(&bank[i], NULL, EmployeeArrive, (void*) &var[i]);
                e++;
            }else{
                var[i].log = log;
                var[i].ID = h;
                pthread_create(&bank[i], NULL, HackerArrive, (void*) &var[i]);
                h++;
            }
        }
    }
    for (i=0; i<E+H; i++){
        pthread_join(bank[i], NULL);
        printf("join %i\n", i);
    }
    return 0;
}

运行:./work -h 4 -e 0 -b 1

它们运行:./work -h 5 -e 0 -b 1

如果他们增加“-h”的值超过 4 个接收段错误

为什么会这样?

最佳答案

pthread_t 数组的分配不太正确。您想要为 pthread_t 实例数组分配存储空间,但目前只为指针分配空间。

如果不为正确的类型分配空间,您以后写入此数组时可能会超出已分配内存的末尾。这有未定义的后果;在这种情况下,您可能会覆盖程序其他部分使用的内存。这很可能会导致段错误。

您应该按如下方式更改分配

pthread_t* bank = malloc((E+H) * sizeof(*bank));

同样的问题适用于 param 数组 var 应该像这样分配

param* var = malloc((E+H) + sizeof(*var));

请注意,稍后在您的程序中释放这些数组是一种很好的做法

for (i=0; i<E+H; i++){
    pthread_join(bank[i], NULL);
    printf("join %i\n", i);
}
free(bank);
free(var);

关于c - 段错误加入线程号 5 (pthread_join),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19594464/

相关文章:

c - 在 hermite 中倾倒的分段故障核心

C sprintf覆盖?

c - 更新一些扫描器代码以使用 ICU 时的问题

java - 使用@Async调用方法与在新线程中调用方法

将数据从一个指针复制到另一个段错误

c++ - 为什么 V8 的 Hello World 在 Ubuntu 上会导致段错误?

c - 为什么while循环会清除一个变量?

c - 哈希表打印 "Stops Working"

java - Jersey 中后台调用的正确处理

java - 线程在中断或停止后不会停止