2012-02-22 6 views
0

나는 eratosthenes를 사용하여 프라임 체 프로그램을 쓰고 있습니다. 나는 8 개의 스레드를 가지며, 각 스레드는 번호 범위 [1, 2^32]의 세그먼트를 담당합니다. 어떤 이유로 스레드 배열의 thread [0]은 스레드가 생성 될 때 스레드가 이동하는 기능을 수행하지 못하는 경우가 있습니다. 다른 것들은 항상 (그것이) 보인다. 이 코드의 문제점을 알려주십시오. 경고하지만, 나는 단지 C++을 배웠고 구문 오류 등이있을 수 있습니다. 버그를 일으키는 것으로 가정합니다. 이것에 시간을 소비하고 그것을 스레드로 좁혔습니다 [0] 항상 함수를 만드는 것은 아닙니다. #define의 값을 변경하여 디버그하기가 더 쉬울 것입니다. 버그는 어느쪽으로 든 발생합니다. 제발, 제가 프로그램을 개선 할 수있는 방법에 대한 다른 의견에 너무 관심이 없습니다. 곧 끝날 예정이므로, 그대로 작동하도록하고 싶습니다. 정말 고마워! 모든 스레드에 전달됩니다이 코드가 일관되게 충돌하지 않는 이유는 무엇입니까?

#include <iostream> 
#include <pthread.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <bitset> 
#include <sys/time.h> 
#include <sys/resource.h> 
#include <sched.h> 
#include <vector> 
#include <math.h> 

using namespace std; 

#define NUM_OF_THREADS 8 
#define TWO_TO_THIRTY_SECOND 1000000 //4294967296 
#define SQRT_TWO_TO_THE_THIRTY_SECOND 1000 //65536 
#define TWO_T0_THIRTY_SECOND_OVER_EIGHT 125000 //536870976 

typedef struct { 
    unsigned long composite_to_remove_index; 
    int thread_index; 
    unsigned long prime_number; 
} thread_info_t; 

bitset<TWO_T0_THIRTY_SECOND_OVER_EIGHT> bitmap[NUM_OF_THREADS]; 
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 
static pthread_t thread[NUM_OF_THREADS]; 


static void * threadFunc(void *arg) 
{ 

    thread_info_t info = *(thread_info_t *)arg; 

    bitmap[info.thread_index][info.composite_to_remove_index] = 1; 
    info.composite_to_remove_index += info.prime_number; 

    int index_to_remove = (int)info.composite_to_remove_index; 

    for(; index_to_remove < TWO_T0_THIRTY_SECOND_OVER_EIGHT; index_to_remove += info.prime_number) 
    { 
     if(bitmap[info.thread_index][index_to_remove] == 0) 
     { 
      bitmap[info.thread_index][index_to_remove] = 1; 
      if(info.thread_index == 0) 
      { 
       cout << "bit " << index_to_remove << ": " << bitmap[info.thread_index][index_to_remove] << "\n"; 
      } 
     } 
    } 

    return NULL; 
} 

int main (int argc, char * argv[]) 
{ 
    int thread_ret_val; 
    vector<unsigned long long> prime_numbers; 
    thread_info_t info; 

    for(unsigned long long i = 2; i < SQRT_TWO_TO_THE_THIRTY_SECOND; i++) 
    { 
     if(bitmap[0][i] == 0) 
     { 
      prime_numbers.push_back(i); 
      info.prime_number = i; 

      for(unsigned long j = 0; j < NUM_OF_THREADS; j++) 
      { 
       if(j == 0) 
        info.composite_to_remove_index = i*2; 
       else 
        info.composite_to_remove_index = (((TWO_TO_THIRTY_SECOND/NUM_OF_THREADS)*j) % i); 
       info.thread_index = (int)j; 


       thread_ret_val = pthread_create(&thread[info.thread_index], NULL, threadFunc, (void*)&info); 
       if(thread_ret_val != 0) 
       { 
        cerr << "create thread error " << strerror(thread_ret_val) << "\n"; 
       } 
      } 

      for(int j = 0; j < NUM_OF_THREADS; j++) 
      { 
       pthread_join(thread[j], NULL); 
      } 
     } 
    } 

    return 1; 
} 
+6

일관성없는 충돌. 그것은 스레드 _do_입니다. –

+0

스택이 충돌 할 때 스택이란 무엇입니까? 내 추측을 보지 않고는 동기화없이 하나 이상의 스레드에서 비트 맵에 액세스하고 있습니다. –

+0

"기능을 수행하지 못했다"는 의미를 설명하십시오. 이 프로그램은 'NUM_OF_THREADS = 1'일 때 동일한 행동을 보이나요? 그렇다면 디버거에서 프로그램을 단계별로 실행할 때 표시되는 내용을 설명하십시오. 또한,이 숙제는 무엇입니까? – bta

답변

1

info 구조는 각 스레드에 대해 고유 의미하지만, 실수로 가끔 스레드간에 공유 여기에 있습니다. 문제는 infopthread_createthreadFunc의 시작 사이에서 변경되지 않을 것이라는 점입니다. pthread_create을 호출 한 후 다음 반복에서 info의 내용을 변경하면 이전 스레드가 실제로 의 첫 번째 줄에 info을 복사하는 경우가 있습니다.

정보 구조가 std::vector이어야하며 info을 사용할 때마다 pthread_create을 호출해야합니다.

+0

aha. 그건 의미가 있습니다. 만약 내가 벡터를 만들고 싶지 않다면, for 루프에서 정보 구조체를 선언 할 수 없기 때문에 모든 루프 이후에 범위를 벗어납니다. – Marty

+0

첫 번째 행이 실행될 때 구조가 살아 있어야하며 루프가 보장되지 않습니다. 각 스레드에게 자체 구조를 제공하거나 하나의 공유 구조에 대한 액세스를 동기화하십시오. 늦은 것은 여기 복잡하고 불필요합니다. 각 스레드는 실제로 자체 구조가 필요합니다. 더하기 측면에서 스레드의 구조를 복사 할 필요가 없습니다. 'std :: vector'의 대안은 각 정보를'new'로 생성하고, 그것을'threadFunc'의 포인터로 전달하고, 포인터로 사용하고, 함수의 끝에'delete'합니다. – Dialecticus

+0

위대한. 나는 벡터를하고있다. 고마워요! – Marty

관련 문제