如何在Java中等待並通知在C/C++中爲兩個或多個線程共享內存?我使用pthread庫。在C/C++共享內存中等待並通知
回答
相反,你會使用等待/通知的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一樣,虛擬喚醒可能來自等待函數,因此您需要在調用信號之前設置一些條件,並在等待的呼叫後進行檢查,並且您需要在一個循環中調用pthread_cond_wait
。和Java一樣,互斥體在你等待的時候被釋放。
與Java不同,在那裏你可以不叫notify
除非你持有的顯示器,你可以實際上調用pthread_cond_signal
沒有持有互斥。然而,它通常不會爲你帶來任何收益,而且通常是一個非常糟糕的主意(因爲通常你想鎖定狀態 - 信號 - 解鎖)。所以最好只是忽略它並像Java一樣對待它。
其實沒有太多的東西,它的基本模式與Java相同,而不是巧合。不過,請閱讀所有這些功能的文檔,因爲有各種標誌和有趣的行爲,你想知道和/或避免。
在C++中,您可以比使用pthreads API做得更好。您至少應該將RAII應用於互斥鎖/解鎖,但取決於您可以使用的C++庫,對於pthreads函數,使用更多的C++ - ish包裝可能會更好。
使用Condition Variables是做這件事:那些使用Linux下的pthread
庫(見鏈接)時可用。
條件變量是 pthread_cond_t類型的變量,並且與使用 適當功能等待 和以後,處理繼續。
如果可用,您可以使用POSIX信號量。 pthread庫有互斥體,這也可能適用於你。谷歌它...
調用pthread_cond_wait和pthread_cond_signal會可用於同步基於條件
如果你不關心可移植性,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));
。
在標題中,您將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:
- 這個代碼不包含一個原始指針(which are treacherous)
- lambda expressions
- 所有其他種類syntactic swagg。
- 1. 忙碌的等待和共享內存
- 2. 等待並通知
- 3. 替代等待,並在java中通知
- 4. java.lang.IllegalMonitorStateException等待並通知
- 5. 等待並通知協調
- 6. 等待並通知問題
- 7. Matlab中的共享內存和等待會話
- 8. 訪問共享資源,鎖定解鎖或等待通知
- 9. 通過共享內存共享指針
- 10. C#併發共享內存
- 11. 在Objective c中等待並通知等價物嗎?
- 12. 等待通知在java
- 13. 等待和通知在android
- 14. 在共享內存
- 15. Java鎖狀態等待並通知:IllegalMonitorStateException
- 16. Java線程等待並通知
- 17. 等待,並通知條件Java
- 18. Java通知並等待異常?
- 19. 線程等待睡眠並通知
- 20. 等待並通知說明要求
- 21. 內存共享
- 22. 在控制器之間共享數據並等待退貨
- 23. CUDA,CC 2.0卡上的共享內存限制
- 24. 在java中等待,通知和notifyall?
- 25. C在有活動等待的子進程之間共享內存時出錯
- 26. 在內存中緩存數據共享
- 27. 等待()和通知()與linelistener
- 28. Groovy的等待/通知
- 29. 關於等待和通知
- 30. 等待()/通知()同步