【问题标题】:libuv signal handling in multithreaded programs多线程程序中的 libuv 信号处理
【发布时间】:2021-12-21 03:40:03
【问题描述】:

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

背景信息:

来自http://docs.libuv.org/en/v1.x/design.html

I/O(或事件)循环 [...] 旨在绑定到单个线程。

但由于我们在一个多线程程序中,signal handlers can be executed by other threads

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

所以我的问题基本上是 libuv 信号处理是否有效as advertised

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

即使在多线程程序中。

【问题讨论】:

    标签: c++ c multithreading libuv


    【解决方案1】:

    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 源代码具有类似的机制。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-25
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 1970-01-01
      相关资源
      最近更新 更多