2013-03-05 25 views
2

我正在寫一個多線程的Eratosthenes Sieve,我必須使用pthreads。我很確定這樣做的方法是使用互斥鎖和cond_waits。我在程序開始時創建了4個線程,然後我不得不強制他們等到Eratosthenes的Sieve找到一個素數。然後,我必須解鎖線程,以便它們可以標記位數組中每個素數的迭代。然後,他們不得不再次阻塞並等待下一個素數,直到Eratosthenes的Sieve算法耗盡新數字。我怎樣才能阻塞線程,直到找到素數,解除阻塞,然後讓他們等到下一個素數?

這是我的線程函數的代碼:

while(!doneFlag){ 
     printf("Thread wile loop\n"); 
     pthread_mutex_lock(&lock); 
     pthread_cond_wait(&cond, &lock); 

     startingPosition = (double)(maxNum/numThreads) * i; 
     endingPosition = (double)(maxNum/numThreads) * (i+1)-1; 
     if(i == numThreads-1){ 
      endingPosition = maxNum; 
     } 
... Until the end of the function ... 
pthread_mutex_unlock(&lock); 
} 
return (void*)0; 

doneFlag是我設置爲1時,埃拉托色尼的篩的算法與所有的數字完成的標誌。我希望while循環和cond_wait()函數會導致線程等待輸入(只要有輸入留給)

以下是main()函數中的Sieve部分:

while(outerCounter < sqrt(maxNum)){ 
    //searching numbers above the current for prime numbers 
    //printf("Sieve While\n"); 
    for(innerCounter = outerCounter+1; innerCounter <= maxNum; innerCounter++){ 
     //not composite 
     //printf("Sieve for\n"); 
     if(composite[innerCounter] == 0){ 

      printf("Prime found: %d\n", innerCounter); 
      pthread_mutex_lock(&lock); 
      pthread_cond_broadcast(&cond); 
      pthread_mutex_unlock(&lock); 

      outerCounter = innerCounter; 
      numPrimes++; 

     } 
    } 
} 
doneFlag = 1; 

不知何故,複合數字未被標記爲複合(儘管有一對夫婦)。我假設因爲它與main()函數的競爭條件有關,它在線程仍在後臺運行時如何繼續找到更多的素數,從而在線程仍在工作時更改素數。

我該如何解決這個問題?我的鎖/ cond_wait設置正確嗎?我很難找到這個在線資源。

謝謝!

編輯:我也想確保我的每個線程都可以同時運行該函數(該函數是將數組中的元素標記爲組合的)。也許互斥體在我的線程函數中不是一個好主意,因爲我希望它們一起運行? (每個線程佔用陣列的不同部分)

+1

一種意見是,你正在使用相同的互斥鎖定,但提到的4個線程並行運行。這可以使用值爲4的計數信號量來完成。否則,只有一個線程可以在最大值時同時運行。 – fayyazkl 2013-03-05 06:29:21

回答

1

Fayyazkl先說。使用計數信號而不是靜音。查看生產者/消費者,這是你正在解決的問題!

所以,我不熟悉你正在使用的算法,但我試圖理解,所以我可以給予更多的幫助。我認爲每個新的素數都是一項新工作?

無論是哪種情況,你需要你的主循環生產是自給自足的工作,這樣工作線程可以拉從作業隊列中一個新的工作,並擁有所有的,它需要的信息。如果作業只是新的素數,那麼將新素數添加到隊列中併發布計數信號(請記住隊列需要同步)

線程將首先掛起計數信號。當信號變成信號時,線程將喚醒並在sem發送信號之前獲取放入隊列中的作業。然後該線程將處理該作業併發布結果。

我覺得你的問題是,你不必產生與明確的作業參數新的就業機會的一種集中的方式,讓兩個或更多的線程醒來並得到同樣的工作,或者一個都不。

+0

我不知道線程可以共享信號量。如果我想讓線程在使用信號量的同時運行,我是否必須定義「線程數」信號量數量? – FeralShadow 2013-03-05 21:41:56

+0

沒有。使用一個信號量,並將其初始化爲「生成」作業的數量。每當一個線程想要一個新工作時,它就會將信號量減1。如果沒有工作,那麼該線程將進入休眠狀態,直到工作生產者產生一個新工作。遞減/等待信號量的過程是原子和阻塞的,並且將始終以其中一個作業的所有權返回。 (除非它返回失敗代碼)。 – 2013-03-06 07:58:37