最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Wait for file input or a signal in Linux - Stack Overflow

programmeradmin2浏览0评论

I can wait for one of several network connections using select or epoll. I can wait for a signal using sigwaitinfo, or add a handler to run on receipt of the signal.

How do I wait for either a network socket to have incoming traffic, or for a specific signal (SIGWINCH, in my case)?

One idea that occurs to me is to have the signal handler send "loopback" traffic to some open file descriptor, so epoll can await it. But I'd rather not actually make any file. Maybe there's a way to create two new file descriptors which are directly connected to one another?

I can wait for one of several network connections using select or epoll. I can wait for a signal using sigwaitinfo, or add a handler to run on receipt of the signal.

How do I wait for either a network socket to have incoming traffic, or for a specific signal (SIGWINCH, in my case)?

One idea that occurs to me is to have the signal handler send "loopback" traffic to some open file descriptor, so epoll can await it. But I'd rather not actually make any file. Maybe there's a way to create two new file descriptors which are directly connected to one another?

Share Improve this question asked 2 days ago Zachary VanceZachary Vance 8625 silver badges19 bronze badges 3
  • 2 Both select and epoll_wait will wake up and return with EINTR if any signal arrives while they are waiting (you should handle the signal you're interested in and atomically set a flag there or something). So is that already the answer or is there something that prevents you from using that? (e.g. you're multithreaded and your signals are delivered to weird threads...) – teapot418 Commented 2 days ago
  • You are close to rediscovering Daniel J. Bernstein's self-pipe trick. – pilcrow Commented yesterday
  • 1 @teapot418, unfortunately that technique is prone to race conditions. pselect and masking are one mitigation, though turning a signal into an i/o event is a better approach in my opinion. – pilcrow Commented yesterday
Add a comment  | 

2 Answers 2

Reset to default 4

On Linux, I'd do this with signalfd(2), which creates a file descriptor that polls as readable when given signals are delivered (and can be read from to find out information about the signal). That descriptor can be added to the ones monitored by epoll, along with the sockets.

You should block SIGWINCH first with sigprocmask(2) so it doesn't get handled by normal signal handlers.


One idea that occurs to me is to have the signal handler send "loopback" traffic to some open file descriptor, so epoll can await it. But I'd rather not actually make any file. Maybe there's a way to create two new file descriptors which are directly connected to one another?

You can use pipe(2) to create a pair of connected descriptors for that style; it's a common technique for this sort of scenario in older and/or portable code bases. With Linux I generally prefer the lighter weight eventfd(2) for asynchronous notifications, though.

You've several options for a single thread to respond to both signals and I/O.

1. Turn the signals into I/O

This is the approach you'd thought of, and which another answer covers well. You've got the old (and portable) self-pipe trick and the Linux-specific signalfd.

This is what I would do, and I'd suggest upvoting and accepting that other answer.

2. Turn the I/O into signals

For completeness it bears mentioning that you can use fcntl to manage signals, using F_SETOWN and O_ASYNC to get a SIGIO delivered when a descriptor is ready for reading or writing.

With SA_SIGINFO and, on Linux, an explicit F_SETSIG, you'll be able to tell which descriptor is ready and why.

Definitely more awkward than #1 and perhaps inappropriate if some of your descriptors are perpetually writeable, for example. But it might work well for, e.g., waiting for incoming connections on a bound socket.

3. Handle signals and I/O separately, with atomic masking

POSIX's pselect and Linux's ppoll let you use I/O multiplexing without "missing" a signal fire, by atomically unblocking desired signals only during the multiplexing call.

Importantly, select and poll are race-prone here, which other questions on this site cover.

发布评论

评论列表(0)

  1. 暂无评论