我想在我的應用程序中寫入暫停/取消暫停所有線程,這是由SIGUSR1(暫停)和SIGUSR2(取消暫停)激活的。我想在所有線程中使用pthread_cond_wait()
,並且當收到信號時,在條件上使用pthread_cond_broadcast()
我會掛起所有線程,但顯然在信號處理程序中使用pthread_cond_broadcast()
是不安全的...是否有任何其他解決方案來解決此問題(我必須避免忙等待)?pthread - 暫停/暫停所有線程
回答
您可以使用sigwait用於等待信號的專用線程。當收到信號時,返回等待狀態,給定線程可以通知正常代碼(不是信號處理程序)內的其他線程。
假設你有暫停功能及恢復線程像這些
int paused;
pthread_mutex m;
pthread_cond cond;
void pause_threads(void)
{
pthread_mutex_lock(&m);
paused = 1;
pthread_mutex_unlock(&m);
}
void unpause_threads(void)
{
pthread_mutex_lock(&m);
paused = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&m);
}
專用線程可以通過這種方式來實現:
// Block signals for wait
sigset_t usr_set;
sigemptyset(&usr_set);
sigaddset(&usr_set, SIGUSR1);
sigaddset(&usr_set, SIGUSR2);
pthread_sigmask(SIG_BLOCK, &usr_set, NULL);
// If other threads will be created from given one, they will share signal handling.
// Otherwise actions above should be repeated for new threads.
int sig;
// Repeatedly wait for signals arriving.
while(!sigwait(&usr_set, &sig)) {
if(sig == SIGUSR1) {
pause_threads();
}
else {
unpause_threads();
}
}
這是正確的方向。三個評論。首先,沒有必要將信號的配置更改爲SIG_IGN,因爲sigwait沒有_delivering_接收待處理信號。其次,我們知道代碼是多線程的,因此必須使用'pthread_sigmask'而不是'sigprocmask'(多線程代碼中未定義的行爲)。第三,這個答案是不完整的 - 它需要像[@ Martinn的回答](http://stackoverflow.com/a/34386678/132382)這樣的東西結婚成爲一個完整的解決方案。 – pilcrow
@pilcrow:謝謝你的評論!在我認爲應該處理任何捕獲的信號之前(當未被阻塞時)。現在我看到'sigwait'是該規則的例外。至於第三條評論,根據問題,OP肯定知道如何處理捕獲的信號。但我爲了illustrativness的目的添加了一些示例代碼。 – Tsyvarev
你有沒有嘗試過這樣的事情:
pthread_mutex_lock(&m_suspend_mutex);
while (m_suspend_flag == 1)
{
pthread_cond_wait(&m_resume_cond, &m_suspend_mutex);
}
pthread_mutex_unlock(&m_suspend_mutex);
這將暫停線程,直到另一個線程設置m_suspend_flag
爲0。這可以被放置在一個戰略位置,在你的線程執行週期。對於您的場景,您可以在線程檢查消息隊列中是否有任何消息之後放置這一小段代碼。
- 1. 暫停pthread?
- 2. 線程暫停
- 3. 暫停和取消暫停線程
- 4. 暫停和停止線程
- 5. PyCharm - 如何暫停所有線程
- 6. 主線程暫停
- 7. Ruby暫停線程
- 8. 暫停所有javascript
- 9. 如何在主線程停止/暫停線程/ Activity在android中暫停/停止?
- 10. 如何停止visual studio去program.cs(暫停所有)暫停按鈕
- 11. 在創建soundloop之前停止/暫停所有線程
- 12. 暫停下載線程
- 13. WPF - 暫停UI線程?
- 14. 「暫停」,線程與屬性
- 15. 暫停/恢復線程?
- 16. 暫停後臺線程()
- 17. 什麼是暫停線程?
- 18. 是主線程暫停嗎?
- 19. Java InterruptedException暫停線程?
- 20. 暫停在工作線程
- 21. 暫停Windows服務線程?
- 22. Android:暫停線程幾秒
- 23. C# - 多線程暫停
- 24. 暫停線程週期(android)
- 25. 殺死暫停的線程
- 26. 暫停Web請求(線程)
- 27. 暫停和恢復線程
- 28. Python暫停線程執行
- 29. Android/Java - 暫停線程
- 30. 在ExitDialog上暫停線程
的每一個地方,例如我不能暫停線程如果他們正在等待來自其他進程的消息的消息隊列,則應該在暫停之前完成此操作。 – qiubit
您的處理循環是如何設置的?如果它是基於'select'的,那麼當被任何信號中斷時,'select'將返回一個錯誤,'errno'設置爲'EINTR'。此時您可以發送廣播。或者你甚至可以用'signalfd'將信號明確地加入到你的處理循環中。 – kaylum