[英]wait and notify in C/C++ shared memory
如何在Java中等待和通知在C / C ++中兩個或多個線程之間的共享內存?我使用pthread庫。
您需要兩個對象:互斥鎖和條件變量,而不是您將用於等待/通知的Java對象。 這些是使用pthread_mutex_init
和pthread_cond_init
初始化的。
您將在Java對象上進行同步的位置,請使用pthread_mutex_lock
和pthread_mutex_unlock
(請注意,在C中您必須手動將它們配對)。 如果您不需要等待/通知,只需鎖定/解鎖,那么您不需要條件變量,只需要互斥鎖。 請記住,互斥鎖不一定是“遞歸的”,這意味着如果您已經持有鎖,除非您將init標志設置為表示您想要該行為,否則不能再次使用它。
您將調用java.lang.Object.wait
,調用pthread_cond_wait
或pthread_cond_timedwait
。
你可以調用java.lang.Object.notify
,調用pthread_cond_signal
。
您將調用java.lang.Object.notifyAll
,調用pthread_cond_broadcast
。
與在Java中一樣,可以從等待函數中進行虛假喚醒,因此您需要在調用signal之前設置一些條件,並在調用wait之后進行檢查,並且需要在循環中調用pthread_cond_wait
。 與在Java中一樣,在您等待時釋放互斥鎖。
與Java不同,除非您持有監視器,否則無法調用notify
,您實際上可以在不保持互斥鎖的情況下調用pthread_cond_signal
。 但是,它通常不會獲得任何東西,並且通常是一個非常糟糕的主意(因為通常你想要鎖定 - 設置條件 - 信號 - 解鎖)。 所以最好只是忽略它並像Java一樣對待它。
它沒有更多的東西,基本模式與Java相同,而不是巧合。 但是,請閱讀所有這些功能的文檔,因為您需要了解和/或避免各種標記和有趣的行為。
在C ++中,您可以比使用pthreads API做得更好。 您至少應該將RAII應用於互斥鎖定/解鎖,但是根據您可以使用的C ++庫,您可能最好使用更多的C ++ - ish包裝器來實現pthreads功能。
在你的標題中,你將C和C ++混合在一起,隨便進入“C / C ++”。 我希望,你不是在寫一個兩者混合的程序。
如果你正在使用C ++ 11,你會發現一個可移植的(因為C ++,所以)更安全/更容易使用的替代pthreads(在POSIX系統上,它通常使用pthreads)。
您可以使用std::condition_variable
+ std::mutex
進行wait / notify。 此示例顯示如何:
#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的一些其他優勢:
pthread_cond_wait和pthread_cond_signal可用於根據條件進行同步
使用Condition Variables是一種方法:在Linux下使用pthread
庫時可以使用它們(參見鏈接)。
條件變量是pthread_cond_t類型的變量,並與適當的函數一起使用以等待和稍后的進程繼續。
如果您不關心可移植性,Linux會提供eventfd,它可以為您提供所需的內容。 每個eventfd都有一個內部計數器。 在默認模式下,如果計數器為零,則從eventfd塊中讀取,否則立即返回。 寫入它將添加到內部計數器。
等待調用因此只是一個uint64_t buf_a; read(event_fd, &buf_a, sizeof(buf_a));
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));
uint64_t buf_b = 1; write(event_fd, &buf_b, sizeof(buf_b));
。
如果可用,您可以使用POSIX信號量。 pthread庫有互斥,也可能對你有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.