获取Boost deadline_timer原生文件描述符

时间:2017-12-18 20:45:58

标签: c++ linux boost

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

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

其中文件描述符 我想

  1. 使用boost::asio::basic_waitable_timer<std::chrono::steady_clock>
  2. 将其原生 fd 设置为TFD_CLOEXEC
  3. boost没有为boost::asio::basic_waitable_timer<std::chrono::steady_clock>提供 native()功能。

    1. 为什么?
    2. 我可以以某种方式实现这一目标吗?
    3. ----------------------测试----------------------
      fork()的代码示例。在fork() fd传递给儿子 当我从儿子调用一些exec()函数时,fd没有传递给新进程,正如@nos所说。
      仅针对fork()过程,我需要使用notify_fork作为@sehe建议。

      #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]
      

1 个答案:

答案 0 :(得分:2)

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