2010-01-18 24 views

回答

28

相反,你會使用等待/通知的Java對象,你需要兩個對象:互斥和條件變量。這些初始化爲pthread_mutex_initpthread_cond_init

如果您要在Java對象上同步,請使用pthread_mutex_lockpthread_mutex_unlock(注意,在C中,您必須手動將它們配對)。如果你不需要等待/通知,只需鎖定/解鎖,那麼你不需要條件變量,只需要互斥鎖。請記住,互斥鎖不一定是「遞歸的」,這意味着如果你已經持有這個鎖,除非你設置init標誌來表明你想要這種行爲,否則你不能再次使用它。

如果您打電話給java.lang.Object.wait,請致電pthread_cond_waitpthread_cond_timedwait

如果您打電話給java.lang.Object.notify,請致電pthread_cond_signal

如果您打電話給java.lang.Object.notifyAll,請撥打pthread_cond_broadcast

和Java一樣,虛擬喚醒可能來自等待函數,因此您需要在調用信號之前設置一些條件,並在等待的呼叫後進行檢查,並且您需要在一個循環中調用pthread_cond_wait。和Java一樣,互斥體在你等待的時候被釋放。

與Java不同,在那裏你可以不叫notify除非你持有的顯示器,你可以實際上調用pthread_cond_signal沒有持有互斥。然而,它通常不會爲你帶來任何收益,而且通常是一個非常糟糕的主意(因爲通常你想鎖定狀態 - 信號 - 解鎖)。所以最好只是忽略它並像Java一樣對待它。

其實沒有太多的東西,它的基本模式與Java相同,而不是巧合。不過,請閱讀所有這些功能的文檔,因爲有各種標誌和有趣的行爲,你想知道和/或避免。

在C++中,您可以比使用pthreads API做得更好。您至少應該將RAII應用於互斥鎖/解鎖,但取決於您可以使用的C++庫,對於pthreads函數,使用更多的C++ - ish包裝可能會更好。

4

使用Condition Variables是做這件事:那些使用Linux下的pthread庫(見鏈接)時可用。

條件變量是 pthread_cond_t類型的變量,並且與使用 適當功能等待 和以後,處理繼續。

1

如果可用,您可以使用POSIX信號量。 pthread庫有互斥體,這也可能適用於你。谷歌它...

6

調用pthread_cond_wait和pthread_cond_signal會可用於同步基於條件

2

如果你不關心可移植性,Linux提供了eventfd,它提供了你想要的東西。每個eventfd都有一個內部計數器。在默認模式下,如果計數器爲零,則從eventfd塊中讀取,否則立即返回。寫入它將添加到內部計數器。

等待調用將因此只是uint64_t buf_a; read(event_fd, &buf_a, sizeof(buf_a));,其中buf必須是一個8字節的緩衝區。要通知等待的線程,你會做uint64_t buf_b = 1; write(event_fd, &buf_b, sizeof(buf_b));

6

在標題中,您將C和C++混合在一起,如此隨便地放入「C/C++」中。我希望,你不是在編寫一個混合了這兩者的程序。如果你使用C++ 11,你會發現一個可移植的和(因爲C++,所以)更安全/更易於使用的替代pthread的替代品(在POSIX系統上它通常使用pthreads) 。

您可以使用std::condition_variable + std::mutex進行等待/通知。 This example展示瞭如何:

#include <iostream> 
#include <string> 
#include <thread> 
#include <mutex> 
#include <condition_variable> 

std::mutex m; 
std::condition_variable cv; 
std::string data; 
bool mainReady = false; 
bool workerReader = false; 

void worker_thread() 
{ 
    // Wait until main() sends data 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return mainReady;}); 
    } 

    std::cout << "Worker thread is processing data: " << data << std::endl; 
    data += " after processing"; 

    // Send data back to main() 
    { 
     std::lock_guard<std::mutex> lk(m); 
     workerReady = true; 
     std::cout << "Worker thread signals data processing completed\n"; 
    } 
    cv.notify_one(); 
} 

int main() 
{ 
    std::thread worker(worker_thread); 

    data = "Example data"; 
    // send data to the worker thread 
    { 
     std::lock_guard<std::mutex> lk(m); 
     mainReady = true; 
     std::cout << "main() signals data ready for processing\n"; 
    } 
    cv.notify_one(); 

    // wait for the worker 
    { 
     std::unique_lock<std::mutex> lk(m); 
     cv.wait(lk, []{return workerReady;}); 
    } 
    std::cout << "Back in main(), data = " << data << '\n'; 


    // wait until worker dies finishes execution 
    worker.join(); 
} 

此代碼還強調了一些其他的強項,是C++擁有C:

  1. 這個代碼不包含一個原始指針(which are treacherous
  2. lambda expressions
  3. 所有其他種類syntactic swagg