Linux : pthread_cond_signal() 在 Signal Handler() 内部不工作
Linux : pthread_cond_signal() is not working inside a Signal Handler()
Summary
-----------
1. In main() am going for pthread_cond_wait().
2. In signal handler() am waking main() using pthread_cond_signal().
3. But main() is not coming out from pthread_cond_wait().
这里有什么问题?帮帮我。
#include <stdio.h>
myclass *myObj = NULL;
主要是我在等待信号:
int main()
{
myObj = new myclass;
/* do something */
myobj->gotoWait(); <=== Wait blocked for ever.
/* do clean up here */
return 0;
}
向主线程发送信号的信号处理程序:
static void signalHandler(int sig, siginfo_t *siginfo, void *context)
{
myObj->wakeFromWait();
}
实际class实现了信号的等待和发送。
这里有什么问题?
myclass::gotoWait()
{
pthread_mutex_lock(&mtx);
pthread_cond_wait(&cnd, &mtx);
pthread_mutex_unlock(&mtx);
}
myclass::wakeFromWait()
{
pthread_mutex_lock(&mtx);
pthread_cond_signal(&cnd, &mtx);
pthread_mutex_unlock(&mtx);
}
在信号处理程序中,只允许非常有限的系统调用。
见 man 7 signal
http://man7.org/linux/man-pages/man7/signal.7.html
我的建议是,保险起见,所谓"self pipe trick"。
http://man7.org/tlpi/code/online/diff/altio/self_pipe.c.html
您可以启动一个线程,该线程在自管道上运行 select 循环并调用适当的处理程序。
你的代码有什么问题?您正在信号处理程序中锁定一个互斥量
编辑:这里有一个信号指南
http://beej.us/guide/bgipc/output/html/multipage/signals.html
也许您可以使用 sigprocmask() 来确保给定信号不会到达代码中的特定点,然后信号处理程序无法在那一点。
例如:
* 下面的代码是基于这个 James Sullivan's article
lock/unlock(也许)即将到达信号的函数:
void signal_lock (sigset_t *save) {
sigset_t set;
sigfillset(&set); /* fill `set` with __all__ signals */
sigprocmask(SIG_BLOCK, &set, save); /* no more signals :-) */
}
void signal_unlock (sigset_t *save) {
sigprocmask(SIG_SETMASK, save, NULL); /* enable again */
}
调用 signal_lock()
后 ...
sigset_t tmp;
signal_lock(&tmp); /* we locked all signals --
* no signal will arrives until signal_unlock() */
pthread_mutex_lock(<pthread_mutex_t*>);
/* do your stuff */
pthread_mutex_unlock(<pthread_mutex_t*>);
signal_unlock(&tmp); /* unlock signals --
* only signals allowed before signal_lock()
* may arrive */
我建议您通读 James Sullivan 的 amazing article,它更好地解释了事情:-)
Summary
-----------
1. In main() am going for pthread_cond_wait().
2. In signal handler() am waking main() using pthread_cond_signal().
3. But main() is not coming out from pthread_cond_wait().
这里有什么问题?帮帮我。
#include <stdio.h>
myclass *myObj = NULL;
主要是我在等待信号:
int main()
{
myObj = new myclass;
/* do something */
myobj->gotoWait(); <=== Wait blocked for ever.
/* do clean up here */
return 0;
}
向主线程发送信号的信号处理程序:
static void signalHandler(int sig, siginfo_t *siginfo, void *context)
{
myObj->wakeFromWait();
}
实际class实现了信号的等待和发送。
这里有什么问题?
myclass::gotoWait()
{
pthread_mutex_lock(&mtx);
pthread_cond_wait(&cnd, &mtx);
pthread_mutex_unlock(&mtx);
}
myclass::wakeFromWait()
{
pthread_mutex_lock(&mtx);
pthread_cond_signal(&cnd, &mtx);
pthread_mutex_unlock(&mtx);
}
在信号处理程序中,只允许非常有限的系统调用。
见 man 7 signal
http://man7.org/linux/man-pages/man7/signal.7.html
我的建议是,保险起见,所谓"self pipe trick"。 http://man7.org/tlpi/code/online/diff/altio/self_pipe.c.html
您可以启动一个线程,该线程在自管道上运行 select 循环并调用适当的处理程序。
你的代码有什么问题?您正在信号处理程序中锁定一个互斥量
编辑:这里有一个信号指南 http://beej.us/guide/bgipc/output/html/multipage/signals.html
也许您可以使用 sigprocmask() 来确保给定信号不会到达代码中的特定点,然后信号处理程序无法在那一点。
例如:
* 下面的代码是基于这个 James Sullivan's article
lock/unlock(也许)即将到达信号的函数:
void signal_lock (sigset_t *save) {
sigset_t set;
sigfillset(&set); /* fill `set` with __all__ signals */
sigprocmask(SIG_BLOCK, &set, save); /* no more signals :-) */
}
void signal_unlock (sigset_t *save) {
sigprocmask(SIG_SETMASK, save, NULL); /* enable again */
}
调用 signal_lock()
后 ...
sigset_t tmp;
signal_lock(&tmp); /* we locked all signals --
* no signal will arrives until signal_unlock() */
pthread_mutex_lock(<pthread_mutex_t*>);
/* do your stuff */
pthread_mutex_unlock(<pthread_mutex_t*>);
signal_unlock(&tmp); /* unlock signals --
* only signals allowed before signal_lock()
* may arrive */
我建议您通读 James Sullivan 的 amazing article,它更好地解释了事情:-)