2016-04-22 43 views
0

我是Linux中併發和線程概念的新手,我試圖解決一個相對簡單的問題。我創建了兩個線程,它們運行增加一個全局變量的相同函數。我真的從我的節目要的是交替增加變量,即在每個說一步遞增的變量打印到屏幕上一個消息的線程,因此預期的輸出應該是這樣的:Linux中的併發:在臨界區域交替訪問兩個線程

Thread 1 is incrementing variable count... count = 1 
Thread 2 is incrementing variable count... count = 2 
Thread 1 is incrementing variable count... count = 3 
Thread 2 is incrementing variable count... count = 4 

等上。

我試圖確保互斥信號量的實現,但儘管如此其結果類似於此:

Thread 2 is incrementing variable count... count = 1 
Thread 2 is incrementing variable count... count = 2 
Thread 2 is incrementing variable count... count = 3 
Thread 2 is incrementing variable count... count = 4 
Thread 2 is incrementing variable count... count = 5 
Thread 1 is incrementing variable count... count = 6 
Thread 1 is incrementing variable count... count = 7 
Thread 1 is incrementing variable count... count = 8 
Thread 1 is incrementing variable count... count = 9 
Thread 1 is incrementing variable count... count = 10 

我的代碼如下所示:

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

int count = 0; 
sem_t mutex; 

void function1(void *arg) 
{ 
     int i = 0; 
     int *a = (int*) arg; 

     while (i < 10) 
     { 
      sem_wait(&mutex); 
      count++; 
      i++; 
      printf("From the function : %d count is %d\n",*a,count); 
      sem_post(&mutex); 
     } 
} 

int main() 
{ 
    pthread_t t1,t2; 
    int a = 1; 
    int b = 2; 
    pthread_create(&t1,NULL,(void *)function1,&a); 
    pthread_create(&t2,NULL,(void *)function1,&b); 

    sem_init(&mutex,0,1); 
    pthread_join(t2,NULL); 
    pthread_join(t1,NULL); 
    sem_destroy(&mutex); 
    return 0; 
} 

我的大問題是,現在,怎麼辦我在線程之間實現了這種交替?我得到了相互排斥,但這種改變依然不見了。也許我對信號量的使用缺乏洞察力,但如果有人會向我解釋這一點,我將非常感激。 (我已經閱讀了關於這個主題的幾門課程,即Linux信號量,併發和線程,但這些信息還不夠令人滿意)

回答

0

互斥鎖並不保證任何公平性。這意味着如果線程1釋放它然後嘗試再次獲取它,則不能保證它不會 - 它只是保證不能同時在該塊中運行兩段代碼。

編輯:刪除了以前的C風格的解決方案,因爲它可能是不正確的。該問題要求提供同步解決方案。

如果你真的想正確地做到這一點,你會使用一種叫做監視器和警衛(或條件變量)的東西。我不是太熟悉C和並行線程,所以你需要看看如何與做,但在Java它看起來是這樣的:

public class IncrementableInteger { 
    public int value; 

    @Override 
    public String toString() { 
     return String.valueOf(value); 
    } 
    } 

    @Test 
    public void testThreadAlternating() throws InterruptedException { 
    IncrementableInteger i = new IncrementableInteger(); 

    Monitor m = new Monitor(); 
    Monitor.Guard modIsZeroGuard = new Monitor.Guard(m) { 
     @Override public boolean isSatisfied() { 
     return i.value % 2 == 0; 
     } 
    }; 

    Monitor.Guard modIsOneGuard = new Monitor.Guard(m) { 
     @Override public boolean isSatisfied() { 
     return i.value % 2 == 1; 
     } 
    }; 

    Thread one = new Thread(() -> { 
     while (true) { 
     m.enterWhenUninterruptibly(modIsZeroGuard); 
     try { 
      if (i.value >= 10) return; 
      i.value++; 
      System.out.println("Thread 1 inc: " + String.valueOf(i)); 
     } finally { 
      m.leave(); 
     } 
     } 
    }); 

    Thread two = new Thread(() -> { 
     while (true) { 
     m.enterWhenUninterruptibly(modIsOneGuard); 
     try { 
      if (i.value >= 10) return; 
      i.value++; 
      System.out.println("Thread 2 inc: " + String.valueOf(i)); 
     } finally { 
      m.leave(); 
     } 
     } 
    }); 

    one.start(); 
    two.start(); 

    one.join(); 
    two.join(); 
    } 
+0

我已經在我的IDE編寫的代碼,它在第一次打印後實際上會阻塞 – Dragos2795

+0

因此,我不認爲它實際上是阻塞的,可能發生的情況是第一個線程持續獲得互斥鎖。因此,如果您要在if語句之外添加一個說明「線程* a正在運行」的打印,您應該看到它不斷打印出來。那會發生什麼? – Almog