我想在我的应用程序中写入暂停/取消暂停所有线程,这是由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