我有一个多线程应用程序。该应用程序具有以下一组线程:
睡觉的主线程。所有信号都在此线程中被阻止。
执行所有处理的线程t1。此线程中的所有信号都被阻止。
由我使用的第三方组件设置的信号处理线程(t2)。该线程仅等待SIGINT和SIGKILL信号。所有其他信号都在此线程中被阻止。
我自己的自定义信号处理线程(t3)。
现在,为了处理进程退出,我向我的进程发送了一个SIGUSR1。信号将被线程t3捕获。线程t3将调用清理例程并退出。这里的问题是线程t3试图清理其他线程访问的资源。这将导致间歇性崩溃。
显然,我目前的解决方案没有优雅的流程退出处理。我的问题是如何在这种情况下处理流程退出?信号处理线程应如何停止剩余的线程然后退出进程?
或者有没有比发送信号(SIGUSR1)更好的方法来终止进程?
我的应用程序是用C语言编写的,在RHEL 5上运行。
答案 0 :(得分:0)
在清理例程中放置一个互斥锁,这样两个线程就不会立即尝试清理。想要关闭的线程应该获取互斥锁,然后告诉其他线程关闭(无论你通常采用哪种方式)。这样只有一个线程可以进行实际的清理。
void cleanup()
{
pthread_mutex_lock(m);
if (!cleanup_done) {
cleanup_done = 1;
tell_other_threads_to_stop();
wait_for_other_threads_to_finish();
clean_up_common_resources();
}
pthread_mutex_unlock(m);
}
或者,您可以永久锁定所有共享资源,清理它们并在保持锁定的同时终止整个过程。
答案 1 :(得分:0)
在多线程应用程序中处理信号的一个好方法是只有一个线程等待信号,所有其他线程应该阻塞信号。通常,这是初始化所有组件/库,创建其他线程,等待信号并以有序方式终止应用程序的主线程。
目前尚不清楚为什么你的应用程序有线程1和4.线程2可以完成所有工作并处理所有信号(应该是主线程)。通常,让第三方组件处理信号不是一个好主意,因此在线程3中阻止信号可能更好。
应用程序应处理的标准终止信号为SIGINT
(通过ctrl-c
击键发送)和SIGTERM
由kill <app-pid>
发送。
答案 2 :(得分:0)
你的t3必须取消t1 / t2并在调用exit()之前等待终止,因为这里存在竞争条件。
在这种情况下不要懒惰,因为没有别的办法。
顺便说一句,由于你的main()什么都不做,你可以用一个明确的pthread_exit()简单地完成它。