我正在尝试解决一个小同步问题。但是当我加入线程时,我得到了第五次迭代的段错误!如果我只创建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接收分段错误
为什么会这样?
答案 0 :(得分:3)
pthread_t
数组的分配不太对。您希望为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);
答案 1 :(得分: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()
等功能时检查返回,否则你完全不知道你是否忽略了你的功能试图告诉你的重要错误。