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 源代码具有类似的机制。
所以答案应该是肯定的,它也应该像在多线程设置中宣传的那样工作,即注册的处理程序将由循环线程执行。