多线程程序中的 libuv 信号处理
libuv signal handling in multithreaded programs
在主线程正在执行 libuv 事件循环的多线程 C++ 程序中,是否保证此事件循环线程正在执行使用 uv_signal_start
注册的信号处理程序?
背景资料:
来自http://docs.libuv.org/en/v1.x/design.html
The I/O (or event) loop is [...] meant to be tied to a single thread.
但是由于我们在多线程程序中,signal handlers can be executed by other threads
According to POSIX.1, a process-directed signal (sent using kill(2), for example) should be handled by a single, arbitrarily selected thread within the process.
所以我的问题基本上是 libuv 信号处理是否有效 as advertised
Signal handles implement Unix style signal handling on a per-event loop bases.
即使在多线程程序中。
TLDR:是的,应该像宣传的那样工作。
根据我对 libuv 源代码的理解unix/signal.c有一个通用的信号处理程序
static void uv__signal_handler(int signum) {
uv__signal_msg_t msg;
uv_signal_t* handle;
int saved_errno;
saved_errno = errno;
memset(&msg, 0, sizeof msg);
if (uv__signal_lock()) {
errno = saved_errno;
return;
}
for (handle = uv__signal_first_handle(signum);
handle != NULL && handle->signum == signum;
handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
int r;
msg.signum = signum;
msg.handle = handle;
/* write() should be atomic for small data chunks, so the entire message
* should be written at once. In theory the pipe could become full, in
* which case the user is out of luck.
*/
do {
r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
} while (r == -1 && errno == EINTR);
assert(r == sizeof msg ||
(r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));
if (r != -1)
handle->caught_signals++;
}
uv__signal_unlock();
errno = saved_errno;
}
其中一个管道 handle->loop->signal_pipefd[1]
用于告诉句柄的关联 loop
关于传入信号。事实上,这个通用信号处理程序可以从任何线程调用,但是 libuv 线程随后将调用在事件循环线程(主线程)中用 uv_signal_start
注册的用户特定信号处理程序在我的设置中)当它在下一个循环迭代中读取 signal_pipefd[1]
时。
这是针对 unix 源代码的,windows win/signal.c 源代码具有类似的机制。
所以答案应该是肯定的,它也应该像在多线程设置中宣传的那样工作,即注册的处理程序将由循环线程执行。
在主线程正在执行 libuv 事件循环的多线程 C++ 程序中,是否保证此事件循环线程正在执行使用 uv_signal_start
注册的信号处理程序?
背景资料:
来自http://docs.libuv.org/en/v1.x/design.html
The I/O (or event) loop is [...] meant to be tied to a single thread.
但是由于我们在多线程程序中,signal handlers can be executed by other threads
According to POSIX.1, a process-directed signal (sent using kill(2), for example) should be handled by a single, arbitrarily selected thread within the process.
所以我的问题基本上是 libuv 信号处理是否有效 as advertised
Signal handles implement Unix style signal handling on a per-event loop bases.
即使在多线程程序中。
TLDR:是的,应该像宣传的那样工作。
根据我对 libuv 源代码的理解unix/signal.c有一个通用的信号处理程序
static void uv__signal_handler(int signum) {
uv__signal_msg_t msg;
uv_signal_t* handle;
int saved_errno;
saved_errno = errno;
memset(&msg, 0, sizeof msg);
if (uv__signal_lock()) {
errno = saved_errno;
return;
}
for (handle = uv__signal_first_handle(signum);
handle != NULL && handle->signum == signum;
handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) {
int r;
msg.signum = signum;
msg.handle = handle;
/* write() should be atomic for small data chunks, so the entire message
* should be written at once. In theory the pipe could become full, in
* which case the user is out of luck.
*/
do {
r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg);
} while (r == -1 && errno == EINTR);
assert(r == sizeof msg ||
(r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)));
if (r != -1)
handle->caught_signals++;
}
uv__signal_unlock();
errno = saved_errno;
}
其中一个管道 handle->loop->signal_pipefd[1]
用于告诉句柄的关联 loop
关于传入信号。事实上,这个通用信号处理程序可以从任何线程调用,但是 libuv 线程随后将调用在事件循环线程(主线程)中用 uv_signal_start
注册的用户特定信号处理程序在我的设置中)当它在下一个循环迭代中读取 signal_pipefd[1]
时。
这是针对 unix 源代码的,windows win/signal.c 源代码具有类似的机制。
所以答案应该是肯定的,它也应该像在多线程设置中宣传的那样工作,即注册的处理程序将由循环线程执行。