2011-02-10 5 views
0

나는 pthread 라이브러리를 사용하여 소수를 계산하는 프로그램을 만들었습니다. 프로그램은 Cygwin과 Linux에서는 잘 동작하지만 FreeBSD에서는 제대로 작동하지 않습니다. 여기 FreeBSD의 pthreads

그것은 그 pthread_mutex_unlock을이 오류가 발생하지만 난 해결하는 방법을 알아낼 수 없습니다 보인다

This GDB was configured as "i386-marcel-freebsd"... 
(gdb) r 
Starting program: /root/lab/src/sieve/p_sieve 
[New LWP 100060] 
[New Thread 28201140 (LWP 100060)] 
[New Thread 28218140 (LWP 100085)] 
[New Thread 28217ec0 (LWP 100090)] 

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 28218140 (LWP 100085)] 
0x28098f1f in pthread_mutex_unlock() from /lib/libthr.so.3 

프로그램

#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 
#include <math.h> 

#define NUMTHREADS 5 
#define N 10000 

typedef struct 
{ 
    int start; 
    int end; 
}DISTANCE; 

int arr[N]; 

pthread_mutex_t mutex; 

void *sieve(void* s) 
{ 
    int start,end,k,i,j; 
    DISTANCE* d = (DISTANCE*)s; 
    start = d->start; 
    end = d->end; 
    for(i=start;i<end;i++) 
    { 

     if(arr[i]==0) 
     { 
      k = i; 
      for(j=2*k;j<N+1;j+=i) 
      { 

        pthread_mutex_lock(&mutex); 
        arr[j] = 1; 
        pthread_mutex_unlock(&mutex); 

      } 
     } 
    } 
    pthread_exit(NULL); 
} 
void *fill_array(void* f) 
{ 
    int i; 
    arr[0] = 1; 
    arr[1] = 1; 

    for(i=2;i<N;i++) 
    { 
     arr[i] = 0; 
    } 
    pthread_exit(NULL); 
} 
int main(int argc, char **argv) 
{ 

    int div; 
    int status; 
    int i; 
    int count = 0; 
    int nums = 0; 

    pthread_t threads[NUMTHREADS]; 
    DISTANCE dist[NUMTHREADS]; 

    #ifdef NORMAL_FILL_ARRAY 
    arr[0] = 1; 
    arr[1] = 1; 

    for(i=2;i<N;i++) 
    { 
     arr[i] = 0; 
    } 
    #endif 

    #ifdef THREAD_FILL_ARRAY 
    pthread_t p_arr; 
    pthread_create(&p_arr, NULL, fill_array, (void *) NULL); 
    pthread_join(p_arr,NULL); 
    #endif 

    div = ((int)sqrt(N)+1)/NUMTHREADS; 
    pthread_mutex_init(&mutex, NULL); 

    for(i=0;i<NUMTHREADS;i++) 
    { 
     if(i==0) 
     { 
      dist[i].start = 2; 
      dist[i].end = 2 + div; 
     } 
     else if(i==NUMTHREADS-1) 
     { 
      dist[i].start = dist[i-1].end; 
      dist[i].end = (int)sqrt(N)+1; 
     } 
     else 
     { 
      dist[i].start = dist[i-1].end; 
      dist[i].end = dist[i].start + div; 
     } 
     pthread_create(&threads[i],NULL,sieve,(void *)&dist[i]); 
    } 

    for(i=0;i<NUMTHREADS;i++) 
    { 
     if(pthread_join(threads[i],(void **)&status)!=0) 
      printf("pthread_join error"); 
    } 
    pthread_mutex_destroy(&mutex); 

    /*slower with print*/ 
    for(i=0;i<N;i++) 
     { 
       if(arr[i]==0) 
       { 
         #ifdef PRINT 
         printf("%d\t",i); 
         count++; 
         #endif 
         nums++; 
       } 
       #ifdef PRINT 
       if(count==10) 
       { 
         printf("\n"); 
         count = 0; 
       } 
       #endif 
     } 
     #ifdef PRINT 
     printf("\n"); 
     #endif 
    printf("%d: prime numbers found!\n",nums); 
    pthread_exit(NULL); 
    return 0; 
} 

에게 메이크

COMPILER=gcc 
LIBS=-lpthread -lm 
PRINT=-D PRINT 
NORMAL=-D NORMAL_FILL_ARRAY 
THREAD=-D THREAD_FILL_ARRAY 

default: 
    $(COMPILER) $(NORMAL) p_sieve.c -o p_sieve $(LIBS) 
threadfill: 
    $(COMPILER) $(THREAD) p_sieve.c -o p_sieve $(LIBS) 
default_p: 
    $(COMPILER) $(NORMAL) $(PRINT) p_sieve.c -o p_sieve $(LIBS) 
threadfill_p: 
    $(COMPILER) $(NORMAL) $(PRINT) p_sieve.c -o p_sieve $(LIBS) 
debug: 
    $(COMPILER) $(NORMAL) -g p_sieve.c -o p_sieve $(LIBS) 
clean: 
    rm p_sieve 

하고 마침내 gdb를 출력입니다 그것. 아무도 도와 줄 수 있습니까?

+0

프로그램을 정적으로 연결해 보셨습니까? 라이브러리 버전 관리 오류 일 수 있습니다. –

답변

0

필자는 정확히 기억하지 못하고 FreeBSD가 없지만 -pthread 플래그로 컴파일 해보십시오.

+0

그건 도움이 안된다. 문제는 여전히 남아 있습니다. – wallee

+0

@wallee : 프로그램을 컴파일 할 때 사용하는 명령을 제공 할 수 있습니까? ('make'가 출력). 또한 pthread_t 구조체 (비록 구조체인지 기억이 나지 않습니다)가 엉망이되었는지 (누군가가 메모리를 밟았는지 여부)를 볼 수 있습니까? –

2

소스 코드의 세부 사항을 확인하지 않고 - 당신이 어딘가에서 당신의 메모리를 손상시킬 수 있습니다 - 그것은 이상한 SIGSEGV를 설명 할 수 있습니다. 그렇지 않으면 pthread_mutex_unlock()이 코어 덤프를 수행하는 이유가 표시되지 않습니다.

배열 작업을 모두 시도해 보셨습니까? 아니면 거기에 몇 가지 여분의 경계를 넣으시겠습니까?

+0

그것이 문제였습니다. 몇 차례 반복 한 후에 나는 범위를 벗어난 값을 읽었습니다. – wallee

관련 문제