2017-11-06 7 views
0

레이스 조건을 관리하기 위해 내 코드가 필요한 뮤텍스 잠금을 얻지 못하는 문제가 있습니다. 이 코드는 의도적으로 nanosleep을 사용하여 스레드를 일시 중지하고 동일한 데이터에 대해 경쟁하게함으로써 경쟁 조건을 유발합니다. 내 문제는 코드에 뮤텍스 잠금을 추가 할 때 모든 스레드가 실행되지 않아서 잘못된 값을 제공한다는 것입니다.레이스 컨디션 컨트롤에 대한 Pthreads 및 뮤텍스

#include <stdio.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <time.h> 
#include <sys/time.h> 

#define NUM_THREADS 10 

//Global Value 
int SHARED_VALUE = 0 ; 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

void* add10(void*); 
struct timespec ts = {0, 10}; 


int main() { 
    //Required for thread creation 
    pthread_t thread_id; //Thread Identifier 
    pthread_attr_t attributes; //Default Attributes 
    pthread_attr_init(&attributes); //Attributes Initialized to Default   Values 

    //Initialize Mutex 
    if (pthread_mutex_init(&lock, NULL) != 0){ 
     fprintf(stderr,"Error Creating Mutex\n"); 
     return -100; 
    } 
    //Spawn 10 Threads 
    for(int i = 0; i < NUM_THREADS;i++){ 

     thread_id = i+1; 

    if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0) { 
      fprintf(stderr,"Error Creating Thread: %d", thread_id); 
      return -100; 
    } 
} 


for(int i = 0; i < NUM_THREADS; i++){ 
    pthread_join (thread_id,NULL); 
} 

//pthread_mutex_destroy(&lock); 

printf("Shared_Value: %d", SHARED_VALUE); 

}

void* add10(void* arg) { 
    int thread_id = (int *) arg; 
    if ((pthread_mutex_lock(&lock)) == 0) { 
     fprintf(stderr, "Lock Acquired:%d\n", (int *) arg); 
     //Access Shared Value 
     int local_value = SHARED_VALUE; 
     fprintf(stderr, "\tInitial Local Value: %d\n", local_value); 
     local_value = local_value + 10; 
     fprintf(stderr, "\tPost Local Value: %d\n", local_value); 
     //Stall thread for race conditions 
     nanosleep(&ts, NULL); 
     SHARED_VALUE = local_value; 
    } else { 
     fprintf(stderr, "No Lock!\n"); 
     pthread_exit; 
    } 
    if ((pthread_mutex_unlock(&lock)) < 0) { 
     fprintf(stderr, "Error on unlock\n"); 
    } 
} 

출력 체감 보이는 : 당신은 모두 같은 변수 thread_id를 사용하는

Lock Acquired:5 
    Initial Local Value: 0 
    Post Local Value: 10 
Lock Acquired:6 
    Initial Local Value: 10 
    Post Local Value: 20 
Lock Acquired:4 
    Initial Local Value: 20 
    Post Local Value: 30 
Lock Acquired:7 
    Initial Local Value: 30 
    Post Local Value: 40 
Lock Acquired:9 
    Initial Local Value: 40 
    Post Local Value: 50 
Lock Acquired:10 
    Initial Local Value: 50 
    Post Local Value: 60 
Shared_Value: 60Lock Acquired:8 

Process finished with exit code 0 
+0

INT 주() => 0을 반환 ; –

+0

응답에 설명 된대로 'main() 종료 초기'문제를 해결 한 경우에도 'nanosleep (& ts, NULL);' 문제가있다. 신호에 따라 쓰는 것이기 때문에 실제로는 로컬 쓰레드가 필요합니다. 그러나이 경우에는 그냥 웃기는 일입니다. 더 중요한 것은 10ns의 sleep에 대한 요청은 불합리한 요청이며, 잘 다듬어 진 지연이 발생하더라도 자체 오버 헤드와 printf() 호출의 영향으로 막힐 가능성이 높으며 stdout) 잠금은 어쨌든 스레드의 동작을 직렬화 할 가능성이 있습니다. –

답변

1
for(int i = 0; i < NUM_THREADS;i++){ 
     thread_id = i+1; 
    if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0) 

threads.You 여기에 배열이 필요합니다.

pthread_t thread_id[10]; 
for(int i = 0; i < NUM_THREADS;i++){ 
    if(pthread_create(&thread_id[i],&attributes,add10,thread_id[i]) != 0) 
+0

의견에 감사드립니다. 이것은 실제로 오류를 수정했습니다! –

1

음, 기본적으로는 9 개 스레드 문 작성이 때문에

for(int i = 0; i < NUM_THREADS; i++){ 
      pthread_join (thread_id,NULL); 
    } 

나머지 가입 하나 개의 스레드 만 기다리고 무시됩니다

if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0)