Interrupting epoll_wait with a non-IO event, no si

2019-02-03 14:52发布

Current scenario is epoll_wait over a couple of fds and a queue of possible incoming messages, I'd like the loop below epoll_wait to be executed on IO event or on new message.
Ways I know:

  • Use a time msec timeout and check the queue first thing in the loop
  • Use the self-pipe trick from the queue code when messages become available
  • Interrupt the syscall with a standard signal
  • Use epoll_pwait and refine the previous point

None of the points posted above satisfy me enough and I was wondering if there are any other methods that I haven't found.
Reasons are:

  • Signals are something to avoid on multithreaded code and are not very reliable
  • Timeout one removes part of the benefit of the epoll, only waking with events
  • Self-pipe trick looks the best approach for the moment, but still too much boilerplate

ideas?

2条回答
成全新的幸福
2楼-- · 2019-02-03 15:22

You have enumerated the events that can wake up epoll, so the question really becomes: "How do I reduce the boilerplate for the self-pipe trick?"

The answer to that question really depends on your code, the language and what you are trying to do. I assume you have a thread that processes I/O and you want to do other work in that thread while there is no I/O ready. In the code that manages the epoll loop, it can have an internal handle that is exposed to other parts of the system as a "wake" function or a "submit work" function.

There are libraries that do this, for example boost.asio for C++. However, it isn't difficult to write your own if you're just targeting epoll, and the amount of actual boilerplate code should be minimal once you have a class/module/whatever that deals with the epoll loop.

查看更多
叼着烟拽天下
3楼-- · 2019-02-03 15:24

You can use an eventfd which is effectively the same thing as the self-pipe trick except with fewer file descriptors and less boilerplate (glibc has convenience eventfd_read/write functions for instance).

查看更多
登录 后发表回答