【问题标题】:segmentation fault joining thread number 5 (pthread_join)分段错误加入线程号 5 (pthread_join)
【发布时间】:2013-10-25 15:57:10
【问题描述】:

我正在尝试解决一个同步的小问题。但是当我加入线程时,我得到了第五次迭代的段错误!如果我只创建 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,则会收到分段错误

为什么会这样?

【问题讨论】:

  • 我回滚到初始版本。 (花了 10 分钟才找到明显的错误,但我找不到,因为它们已被修复)修复问题中的错误将使 Q&A 对未来的读者毫无价值。

标签: c multithreading segmentation-fault pthread-join


【解决方案1】:

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

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

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

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

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

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

请注意,您最好稍后在程序中free 这些数组

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

【讨论】:

  • 感谢您的回答,我按照您说的做了,但仍然出现段错误!那可能是?
  • 在修复代码之前,问这样的问题是没有意义的。您不会检查 single 函数之一的返回值,而不是 malloc(),不是 fopen(),不是 pthread_create(),不是 pthread_join,什么都没有。如果您不检查这些函数是否返回指示错误,那么如果您得到一些错误,您不应该感到惊讶。您也没有检查您是否有有效的命令行参数。如果您的代码中出现错误,您应该尝试的第一件事是为其添加适当的错误检查。
  • @CesarJRodriguez 请参阅 Paul Griffiths 的回答。 var 内存大小的计算错误较少,但在我的回答中仍然不正确。
【解决方案2】:

请更仔细地阅读您的代码。这个:

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

应该是这样的:

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

在此更改后,您的代码对我有效(或至少不会崩溃):

paul@local:~/src/c/scratch$ ./thread -h 2 -e 2 -b 2
Create Employee 0
Create Hacker 1
Create Employee 1
Create Hacker 0
join 0
join 1
join 2
join 3
paul@local:~/src/c/scratch$

使用像 valgrind 这样的工具可以帮助您在几分钟内找到它。

正如我在其他评论中提到的,每次调用 malloc()fopen()pthread_create()pthread_join() 等函数时都应该检查返回,否则你完全不知道你是否'忽略了你的函数试图告诉你的重要错误。

【讨论】:

  • 好地方 - +1。我没有注意到原始代码中有两个错误。我花了很长时间才发现您所做的更改,因此我冒昧地编辑了您的答案以突出问题。
  • @simonc:没问题,我自己可能应该考虑突出显示,谢谢!
猜你喜欢
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 2013-04-11
  • 2018-11-06
相关资源
最近更新 更多