2017-04-13 35 views
1

저는 C에 비교적 익숙하지 않습니다. 지금까지는 멀티 스레딩에 대한 경험이 거의 없었습니다. 숫자 배열이 소수인지 복합 요소인지를 계산하는 작은 프로그램을 작성했습니다. 이 잘 작동하지만 더 큰 숫자로 작업 할 때 스레드간에 작업 부하를 나누고 싶습니다.멀티 스레딩을 위해 소수를 어떻게 조각합니까?

일종의 생각이 들지만, C에서 이것을 구현하는 방법을 알 수 없습니다. 간단한 예로서 199라는 소수를 취하면,이 숫자를 코어 수로 나눕니다. (예 : 4) 49.75를 얻으십시오. 이 숫자를 50으로 반올림합니다. 각 스레드에 계산할 범위가 주어집니다.

첫 번째 스레드는 i2에서 50까지, 두 번째 스레드는 i51에서 102로 계산됩니다.

나는 이것이 내가 생각하는 것보다 솔루션이 더 쉽다는 것을 확신한다. 나는 그것을 해결할 수 없다.

내 코드 :

#include <pthread.h> 
#include <inttypes.h> 
#include <stdio.h> 
#include <unistd.h> 

#ifdef _SC_NPROCESSORS_ONLN 
#define NUM_THREADS sysconf(_SC_NPROCESSORS_ONLN) 
#else 
#define NUM_THREADS 1 
#endif 

uint64_t numbers[] = {7,3,19,17,199,333}; // Numbers to check 

void *work(void *n_void_ptr); 
int isPrime(uint64_t n); 

int main() 
{ 
    int rc; 
    pthread_t thread[NUM_THREADS]; 

    for (int i = 0; i < sizeof(numbers)/sizeof(uint64_t); i++) { 
     rc = pthread_create(&thread[i], NULL, work, &numbers[i]); 
    } 

    pthread_exit(NULL); 

    return 0; 
} 

void *work(void *n_void_ptr) 
{ 
    uint64_t *n_ptr = (uint64_t *)n_void_ptr; 

    if (!isPrime(*n_ptr)) { 
     printf("%llu is a prime!\n", *n_ptr); 
    } 

    pthread_exit(NULL); 
} 

int isPrime(uint64_t n) 
{ 
    int count = 0; 
    uint64_t i; // Any number > n/2 cannot be a factor 

    for (i = 2; i < n/2 - 0.5; i++) { 
     if (n % i == 0) { 
      count++; 
     } 

     if (count == 1) { 
      printf("%llu is composite!\n", n); 

      return -1; // n is not prime 
     } 
    } 

    return 0; // n is prime 
} 
+0

왜 건너 뛰는가? –

+0

당신이 한 일은 다른 수의 병렬 검사입니다. 범위를 나누고 싶다고 생각했습니다. –

+0

나의 실수는 위의 내용을 51로 변경 한 것입니다. 궁극적으로 범위를 분할하고 싶지만, 그렇게하는 방법에 대해서는 약간의 차이가 있습니다. –

답변

1

그래서 당신이 원하는 것을 다른 비 중복 범위를 확인하기 위해 다른 스레드를 가지고있다.

범위를 작업자에게 전달하려면 먼저 구조체가 필요합니다. 그래서 우리가 시작 -

typedef struct { 
    int lower; 
    int upper; 
    int number; 
    int result; 
} worker_range; 

지금은 메인에서 나는 당신이 199 점검하고 각 스레드는 50 값을 확인해야합니다 가정합니다. 이

worker_threads **ranges = malloc(sizeof(worker_threads*) * (199/50 + 1)); 

이제 우리는 모든 스레드가 시작되었는지 이제 스레드

int i; 
for (i = 0; i < 199/50 + 1; i++){ //Fix this so that extra threads are not spawned. 
    ranges[i] = malloc(sizeof(worker_range)); 
    ranges[i]->number = 199; 
    ranges[i]->lower = 2 + i * 50; 
    ranges[i]->upper = range->lower + 50; //We are probably okay with a bit of overflow 
    range[i]->result = 0; 
    pthread_create(&thread[i], NULL, work, ranges[i]); 
} 

를 생성 할 필요가 같은

우리는 그들이 끝날 때까지 우리가 기다린 시작합니다.

int flag = 0; 
for (i = 0 ;i < 199/50 + 1; i++) { 
    pthread_join(thread[i]); 
    if(ranges[i]->result == 1) 
     flag = 1; 
    free(ranges[i]); 
} 
if (flag==1){ 
    printf("%d is composite\n",199); 
}else{ 
    printf("%d is prime\n",199); 
} 
free(ranges); 

마지막으로 작업자 기능 -

void* work(void * param) { 
    work_range *range = param; 
    int i; 
    for(i = range->lower, i < range->upper; i++){ 
     if (range->number % i == 0){ 
      (range->result) = 1; 
      break; 
     } 
    } 
} 

난이 도움이되기를 바랍니다.

+0

고맙습니다. 그게 내가 원하는거야. –

+0

pthread 함수의 서명을 확인하고자 할 수 있습니다. 나는 기억에서 썼다. 그리고 그것은 긴 시간이었다. –

+1

제안 : 유일한 소수는 2이므로, 특별히 2를 처리하면 높은 모든 범위는 홀수를 검사하면 필요한 작업이 절반으로 줄어 듭니다. – rossum