多线程程序中的libuv信号处理



在主线程执行libuv事件循环的多线程C++程序中,是否保证该事件循环线程执行使用uv_signal_start注册的信号处理程序?

背景信息:

发件人http://docs.libuv.org/en/v1.x/design.html

I/O(或事件(循环[…]意味着绑定到单个线程。

但由于我们在多线程程序中,信号处理程序可以由其他线程执行

根据POSIX.1,进程导向信号(例如,使用kill(2(发送(应该由进程中任意选择的单个线程处理。

所以我的问题基本上是libuv信号处理是否像广告中的一样工作

信号句柄在每个事件循环的基础上实现Unix风格的信号处理。

即使在多线程程序中也是如此。

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;
}

其中管道CCD_ 2用于告知句柄的相关联的CCD_。事实上,这个通用信号处理程序可以从任何线程调用,但是当libuv线程在下一个循环迭代中读取signal_pipefd[1]时,它将调用在事件循环线程(我设置中的主线程(中用uv_signal_start注册的用户特定信号处理程序。

这是针对unix源代码的,windowswin/signal.c源代码也有类似的机制。

因此,答案应该是肯定的,它也应该像在多线程设置中宣传的那样工作,即注册的处理程序将由循环线程执行。

最新更新