2013-10-25 3 views
0

작은 동기화 문제를 해결하려고합니다. 하지만 스레드에 가입하면 다섯 번째 반복의 세그먼트 오류가 발생합니다! 난 단지 4 스레드가 완벽하게 작동하도록 만듭니다.세그멘테이션 오류가 스레드 번호 5 (pthread_join)에 합류했습니다.

여기 스레드를 수행 할 수있는 몇 가지 기본 사항이있는 코드를 남깁니다. 와

#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 개 이상이 세그먼트 오류

왜이 나타납니다?

+1

초기 개정으로 롤백했습니다. (그들이 해결되었으므로 찾을 수없는 분명한 오류를 찾기 위해 10 분을 소비 한 후) 문제의 오류를 수정하면 향후 독자에게 Q & A가 쓸모 없게됩니다. – wildplasser

답변

2

코드를 자세히 읽으십시오. 이 :

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

이 있어야한다 :

[email protected]:~/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 
[email protected]:~/src/c/scratch$ 

도구 등을 사용하여 :

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

코드는 다음과 변경 후 나를 위해 작동 (또는 적어도 충돌하지 않습니다) valgrind는이 기록을 몇 분 만에 추적 할 수있었습니다.

내 다른 코멘트에서 언급 한 바와 같이, 당신은 그렇지 않으면 당신은 당신이 중요한 오류가 귀하의 기능을 무시하고 있는지 전혀 생각이 없다, 그래서 수익 당신이 malloc(), fopen(), pthread_create(), pthread_join() 같은 함수를 호출 매번 확인하고해야 너에게 말하려고하고있어.

+0

좋은 지점 - +1. 원래 코드에 두 가지 오류가 있음을 알지 못했습니다. 문제를 부각시키기 위해 답을 수정하는 자유를 누렸으므로 내가 바꾼 것을 발견하는 데 나이가 들었습니다. – simonc

+0

@imonc : 아무런 문제가 없을 것입니다. 아마도 저 자신을 강조 할 생각이었습니다. 고마워요! –

3

pthread_t 배열의 할당이 적절하지 않습니다. pthread_t 인스턴스의 배열에 대해 스토리지를 할당하려고하지만 현재 포인터 용 공간 만 할당하고 있습니다.

올바른 유형의 공간을 할당하지 않으면 나중에이 배열에 쓸 때 할당 된 메모리 끝을 초과하여 쓰는 위험이 있습니다. 이것은 정의되지 않은 결과를 낳습니다. 이 경우 프로그램의 다른 부분에서 사용되는 메모리를 덮어 쓸 가능성이 큽니다. 이것은 segfault를 일으킬 수 있습니다. 같은 문제는 그것으로 당신을 위해 좋은 연습이 될 거라고

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

주와 같이 할당해야 param 배열 var 적용

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

을 다음과 같이

당신은 할당을 변경해야합니다 free 나중에 프로그램에서이 배열

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

대답 해 주셔서 감사합니다. 나는 당신이 말한 것을했으나 여전히 세그 폴트를줍니다! 그럴 수 있니? –

+0

코드를 수정할 때까지는 이런 질문을하는 것이 포인트가 아닙니다.당신은'malloc()'이 아닌'fopen()'이 아닌'pthread_create()'가 아닌'pthread_join'가 아닌, 함수의 * 하나의 반환을 체크하지 않는다. 이 함수가 오류를 나타내는 지 여부를 확인하지 않으면 어떤 것이 있으면 놀라지 말아야합니다. 유효한 명령 줄 인수가 있는지 여부도 확인하지 않습니다. 코드에 오류가 발생하면 먼저 적절한 오류 검사를 추가해야합니다. –

+0

@CesarJRodriguez Paul Griffiths 대답을 참조하십시오. 'var'의 메모리 크기에 대한 계산은 덜 잘못되었지만 여전히 답이 잘못되었습니다. – simonc