2012-06-29 4 views
0

내 프로그램의 출력을 동기화하기 위해 pthread 뮤텍스 변수와 장벽을 사용하려하지만 원하는 방식으로 작동하지 않습니다. 각 thread는 최종 값을 for 루프에서 오는 매 20 개의 값으로 보았습니다.하지만 모두 최종 값이 같도록하려고합니다. (5 개의 스레드를 사용하는 경우 모두 100을 최종 값으로보아야합니다. , 스레드 4 개 포함, 80 등)C에서 mutex와 barrier를 사용하여 스레드 동기화

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

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 

int SharedVariable =0; 
void *SimpleThread(void *args) 
{ 
    int num,val,rc; 
    int which =(int)args; 
    rc = pthread_mutex_lock(&mutex1); 
    for(num=0; num<20; num++){ 
#ifdef PTHREAD_SYNC 
     if(random() > RAND_MAX/2) 
      usleep(10); 
#endif 
     //pthread_mutex_lock(&mutex1); 
     val = SharedVariable; 
     printf("*** thread %d sees value %d\n", which, val); 
     //pthread_mutex_lock(&mutex1); 
     SharedVariable = val+1; 
     pthread_mutex_unlock(&mutex1); 
    } 
    val=SharedVariable; 

    printf("Thread %d sees final value %d\n", which, val); 
    //pthread_mutex_destroy(&mutex1); 
    //pthread_exit((void*) 0); 
    //pthread_mutex_unlock(&mutex1); 

} 

int main (int argc, char *argv[]) 
{ 
    if(atoi(argv[1]) > 0){   
    int num_threads = atoi(argv[1]); 
    //pthread_mutex_init(&mutex1, NULL); 
    pthread_t threads[num_threads]; 
    int rc; 
    long t; 
    rc = pthread_mutex_lock(&mutex1); 
    for(t=0; t< num_threads; t++){ 
     printf("In main: creating thread %ld\n", t); 
     rc = pthread_create(&threads[t], NULL, SimpleThread, (void*)t); 
     if (rc){ 
     printf("ERROR; return code from pthread_create() is %d\n", rc); 
     exit(-1); 
     } 

    //pthread_join(thread1); 

    } 
    rc= pthread_mutex_unlock(&mutex1); 
} 
    else{ 
     printf("ERROR: The parameter should be a valid positive number."); 
     exit(-1); 
    } 

    pthread_mutex_destroy(&mutex1); 
    pthread_exit(NULL); 
} 

대단히 감사합니다. 고맙습니다!

답변

2

최종 값을 확인하기 전에 장벽 (pthread_barrier_wait())을 사용해야합니다. 이렇게하면 모든 스레드가 장벽에 도달 할 때까지 스레드가 진행되지 않습니다. 또한

, 당신은 스레드가 끝날 때까지 기다려야 pthread_join()를 호출해야하며, 만 증가 주위에 뮤텍스를 유지해야합니다

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

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; 
pthread_barrier_t barrier1; 

int SharedVariable = 0; 

void *SimpleThread(void *args) 
{ 
    int num,val; 
    int which = (int)args; 

    for(num = 0; num < 20; num++) { 
#ifdef PTHREAD_SYNC 
     if(random() > RAND_MAX/2) 
      usleep(10); 
#endif 
     pthread_mutex_lock(&mutex1); 
     val = SharedVariable; 
     printf("*** thread %d sees value %d\n", which, val); 
     SharedVariable = val + 1; 
     pthread_mutex_unlock(&mutex1); 
    } 

    pthread_barrier_wait(&barrier1); 

    val = SharedVariable; 
    printf("Thread %d sees final value %d\n", which, val); 
    return 0; 
} 

int main (int argc, char *argv[]) 
{ 
    int num_threads = argc > 1 ? atoi(argv[1]) : 0; 

    if (num_threads > 0) { 
     pthread_t threads[num_threads]; 
     int rc; 
     long t; 

     rc = pthread_barrier_init(&barrier1, NULL, num_threads); 

     if (rc) { 
      fprintf(stderr, "pthread_barrier_init: %s\n", strerror(rc)); 
      exit(1); 
     } 

     for (t = 0; t < num_threads; t++) { 
      printf("In main: creating thread %ld\n", t); 
      rc = pthread_create(&threads[t], NULL, SimpleThread, (void*)t); 
      if (rc) { 
       printf("ERROR; return code from pthread_create() is %d\n", rc); 
       exit(-1); 
      } 
     } 

     for (t = 0; t < num_threads; t++) { 
      pthread_join(threads[t], NULL); 
     } 
    } 
    else { 
     printf("ERROR: The parameter should be a valid positive number.\n"); 
     exit(-1); 
    } 

    return 0; 
} 
+0

이는 ARGV를 읽고 [1] 그것은 시작 숫자는 첫 번째 숫자를 읽고 나머지는 무시합니다. 예를 들어 "3sdfsdf"가 3 개의 스레드를 생성합니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까? – randomizertech

+0

@ fgualda87 :'atoi()'대신'strtol()'을 사용하십시오 - 변환 된 숫자 뒤의 첫 번째 문자를 알려주며 전체 문자열이 유효한지 확인할 수 있습니다. 이것이 명확하지 않은 경우 다른 질문으로 질문하십시오. – caf

1

SimpleThread에서 for 루프 대신 pthread_mutext_unlock(&mutext1)을 이동하십시오. 한 번만 잠그고 원래 코드에서 mutiple (20) 번을 잠금 해제합니다.

또는 SharedVariable을 읽고 수정하기 전에 pthread_mutex_lock(&mutext1)을 for 루프로 이동할 수 있습니다. 이 경우 각 스레드의 add-by-one 작업은 연속적이지 않을 수 있지만 각 스레드는 올바른 최종 값을 가져옵니다.

그리고 SharedVariable의 최종 값을 읽기 전에 장벽을 사용하여 모든 스레드가 작업을 마칠 때까지 기다리십시오.