Linux中的AFAIK deadline_timer使用timerfd_create()-文件描述符创建。boost为大多数fd包装器提供native()函数;

  • boost::asio::posix::stream_descriptor
  • boost::asio::ip::tcp::socket
  • ...

  • 也是文件描述符。
    我想
  • 使用boost::asio::basic_waitable_timer<std::chrono::steady_clock>
  • 将其 native fd设置为TFD_CLOEXEC

  • 但是boost没有为boost::asio::basic_waitable_timer<std::chrono::steady_clock>提供native()函数。
  • 为什么?
  • 我能以某种方式实现吗?

  • ----------------------测试----------------------fork()的代码示例。在fork()中,fd被传递给儿子。
    当我从儿子那里调用一些exec()函数时,正如@nos所说,fd不会传递给新进程。
    对于仅fork() ed进程,我将需要按@sehe的建议使用notify_fork
    #include <iostream>
    #include <thread>
    #include <chrono>
    #include "boost/asio.hpp"
    #include <unistd.h>
    int main() {
    
        boost::asio::io_service ioService;
        boost::asio::deadline_timer deadlineTimer(ioService);
    
        std::string who;
        pid_t pid = fork();
        if (pid > 0) {
            // Parent
            who = "father, pid " + std::to_string(getpid()) + ", son pid: " + std::to_string(pid);
        } else if (pid == 0) {
            // Child
            who = "son, pid " + std::to_string(getpid());
            // Call some `exec()` here
        } else {
            return -1;
        }
    
        std::cout << who << ", waiting..." << std::endl;
    
        while (true) {
            std::this_thread::sleep_for(std::chrono::seconds(10));
        }
        return 0;
    }
    

    然后我从fdproc检查了lsof:
    me@ubuntu:~$ ll /proc/48564/fd
    total 0
    dr-x------ 2 cgs cgs  0 Dec 19 10:40 ./
    dr-xr-xr-x 9 cgs cgs  0 Dec 19 10:40 ../
    lrwx------ 1 cgs cgs 64 Dec 19 10:40 0 -> /dev/pts/0
    l-wx------ 1 cgs cgs 64 Dec 19 10:40 1 -> /dev/pts/29
    l-wx------ 1 cgs cgs 64 Dec 19 10:40 2 -> /dev/pts/31
    lrwx------ 1 cgs cgs 64 Dec 19 10:40 3 -> anon_inode:[eventfd]
    lrwx------ 1 cgs cgs 64 Dec 19 10:40 4 -> anon_inode:[eventpoll]
    lrwx------ 1 cgs cgs 64 Dec 19 10:40 5 -> anon_inode:[timerfd]
    me@ubuntu:~$ ll /proc/48568/fd
    total 0
    dr-x------ 2 cgs cgs  0 Dec 19 10:41 ./
    dr-xr-xr-x 9 cgs cgs  0 Dec 19 10:41 ../
    lrwx------ 1 cgs cgs 64 Dec 19 10:41 0 -> /dev/pts/0
    l-wx------ 1 cgs cgs 64 Dec 19 10:41 1 -> /dev/pts/29
    l-wx------ 1 cgs cgs 64 Dec 19 10:41 2 -> /dev/pts/31
    lrwx------ 1 cgs cgs 64 Dec 19 10:41 3 -> anon_inode:[eventfd]
    lrwx------ 1 cgs cgs 64 Dec 19 10:41 4 -> anon_inode:[eventpoll]
    lrwx------ 1 cgs cgs 64 Dec 19 10:41 5 -> anon_inode:[timerfd]
    

    最佳答案

    boost::asio::basic_waitable_timer<std::chrono::steady_clock>不是文件描述符。

    在Linux上,您与io_service关联的waitable_timer是(据我所知通常是)timerfd。有一个timerfd用于维护所有计时器。我看不到任何API来访问该文件描述符。

    如果内核支持,则已经使用TFD_CLOEXEC创建了一个文件描述符,该代码如下:

    int epoll_reactor::do_timerfd_create()
    {
    #if defined(BOOST_ASIO_HAS_TIMERFD)
    # if defined(TFD_CLOEXEC)
      int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
    # else // defined(TFD_CLOEXEC)
      int fd = -1;
      errno = EINVAL;
    # endif // defined(TFD_CLOEXEC)
    
      if (fd == -1 && errno == EINVAL)
      {
        fd = timerfd_create(CLOCK_MONOTONIC, 0);
        if (fd != -1)
          ::fcntl(fd, F_SETFD, FD_CLOEXEC);
      }
    

    08-05 04:23
    查看更多