2017-09-25 42 views
0

下一個代碼通常打印BA,但有時它可以打印BBAA,BAAB,... ...這怎麼可能得到兩個A或B吧?但是,這段代碼從不打印三個A或B.這兩個函數(生產和消費)都運行很多線程。提前謝謝了。奇線程行爲

int permission; 
void set_permission(int v) { 
    permission = v; 
    printf("%c", v + 'A');fflush(stdin); 
} 
void* produce(void*) { 
    for (;;) { 
     pthread_mutex_lock(&mr1); 
     set_permission(1); 
     while (permission == 1); 
     pthread_mutex_unlock(&mr1); 
    } 
} 
void* consume(void*) { 
    for (;;) { 
     pthread_mutex_lock(&mr2); 
     while (permission == 0); 
     set_permission(0); 
     pthread_mutex_unlock(&mr2); 
    } 
} 
+5

'fflush(標準輸入);'導致udnefined行爲;不要做 –

+1

我看到2個不相關的互斥體。看起來您可以刪除同步過程並獲得相同的結果。 –

+0

關於兩個不同的互斥體的引用是什麼?如果代碼試圖保護變量'permission',那麼所有的互斥量引用應該是同一個互斥量。建議:for(;;){while(!permission);的pthread_mutex_lock(&mr1); set_permission(1);調用pthread_mutex_unlock(&mr1);}'消費者線程看起來非常相似,並且將使用相同的互斥 – user3629249

回答

4

您的線程不同步,因爲它們不使用相同的互斥鎖。

其他線程可以通過只偶然奶源設置permission爲1或0,但不能管理產生輸出呢。在這種情況下,看起來好像第一個線程運行了兩輪。

當內核之間的內存同步並且兩個線程都寫入時,相應線程的寫入也可以完全獲得丟失。互斥體也可以防止這種情況發生,因爲它建立了一個嚴格的內存訪問順序,簡單來說,它保證了在一個互斥體的保護下發生的所有事情對同一個互斥體的下一個用戶完全可見。

3次或更多次打印相同的字符將是非常不可能的,因爲有至多一個寫之間發生的,所以至多一個寫丟失,或一個無序的輸出。雖然這並不能保證。

如果您的系統上沒有隱含內存同步工作可言,你的代碼也只是直出僵局,下一個互斥體完成寫入從未傳播到另一個的用戶。 (實際上並沒有發生,因爲仍然有一些同步由IO操作介紹。)

+0

我在作業前放置了printf,這消除了所有雙字符!太感謝了! – vollitwr

+1

@vollitwr只要你不使用相同的互斥量,這仍然只是消除了亂序輸出。你的代碼仍然容易丟失寫入,除非'permission'是[atomic](http://de.cppreference.com/w/cpp/atomic/atomic),或者你正在使用相同的互斥體。這個錯誤很難激發,但它仍然會發生。 – Ext3h