获取Boost deadline_timer原生文件描述符

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了获取Boost deadline_timer原生文件描述符相关的知识,希望对你有一定的参考价值。

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

但是boost没有为boost::asio::basic_waitable_timer<std::chrono::steady_clock>提供native()函数。

  1. 为什么?
  2. 我能以某种方式实现这一目标吗

----------------------测试---------------------- fork()的代码示例。在fork()fd被传递给儿子。 当我从儿子那里调用一些exec()函数时 - fd没有被传递给新进程,正如@nos所说。 对于fork()ed进程,我需要使用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;
}

然后我检查了来自fdproclsofs:

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

以上是关于获取Boost deadline_timer原生文件描述符的主要内容,如果未能解决你的问题,请参考以下文章

如何避免触发已经破坏的 boost::asio::deadline_timer

使用许多 boost::asio::deadline_timer [重复]

如何在 Qt 中使用 boost::asio::deadline_timer?

boost::asio::deadline_timer 绑定到多态套接字类指针

使用boost的deadline_timer实现一个异步定时器

在两个线程之间共享deadline_timer