2012-04-26 66 views
0

在多線程中編寫我的基本程序,遇到了一些困難。多線程程序中的輸出

在下面,如果我給位置1處隨後的共享數據的值睡眠正在打印的程序始終是10,同時保持睡眠在位置2的共享數據的值始終爲0

爲什麼這種輸出的是來了? 如何決定在哪個地方我們應該睡覺。 這是否意味着,如果我們把睡眠的互斥體則並不是在所有的這樣的共享數據是0

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

    pthread_mutex_t lock; 

    int shared_data = 0; 

    void * function(void *arg) 
    { 
     int i ; 
     for(i =0; i < 10; i++) 
     { 
      pthread_mutex_lock(&lock); 
      shared_data++; 
      pthread_mutex_unlock(&lock); 
     } 

     pthread_exit(NULL); 
    } 


    int main() 
    { 
     pthread_t thread; 
     void * exit_status; 
     int i; 

     pthread_mutex_init(&lock, NULL); 

     i = pthread_create(&thread, NULL, function, NULL); 

     for(i =0; i < 10; i++) 
     { 
      sleep(1);  //POSITION 1 
      pthread_mutex_lock(&lock); 
      //sleep(1); //POSITION 2 
      printf("Shared data value is %d\n", shared_data); 
      pthread_mutex_unlock(&lock); 
     } 

     pthread_join(thread, &exit_status); 

     pthread_mutex_destroy(&lock); 
    } 

回答

2

當你睡你鎖定互斥之前,那麼你執行的其他線程」重新給其他線程足夠的時間來改變共享變量的值。這就是爲什麼你在位置#1看到「睡眠」的值爲「10」。

當您首先獲取互斥鎖時,您可以將其快速鎖定,以便在其他線程有機會修改該值之前打印出該值。另一個線程坐在並阻止pthread_mutex_lock()調用,直到主線程完成休眠並解除鎖定。此時,第二個線程最終會運行並更改該值。這就是爲什麼你在位置#2看到「睡眠」值爲「0」的原因。

這是一個經典的競賽條件。在另一臺機器上,在位置#2調用sleep時,相同的代碼可能不會顯示「0」。第二個線程完全有可能在您的主線程鎖定互斥鎖之前更改一次或兩次該變量的值。互斥體可以確保兩個線程不會同時訪問同一個變量,但它不能控制兩個線程訪問它的順序。

2

我在這裏有一個完整的解釋,但最終刪除它。這是一個基本的同步問題,在處理更復雜的問題之前,您應該能夠跟蹤和識別它。

但我會給你一個提示:只有位置1的sleep()重要;鎖內的另一個不相關,只要它不改變鎖外的代碼。