4 ms·
Signals are definitely a pain point on Unix - they're decently easy to implement on the OS side, but you just have to think there was a better way. As one of th
by DSMan195276 9y ago
Signals are definitely a pain point on Unix - they're decently easy to implement on the OS side, but you just have to think there was a better way. As one of the commenters on the article pointed out, at this point the best/easiest way to work with them is to just process them on a separate thread and then turn them into events you can handle in your main logic (via the 'self-pipe-trick' or similar ideas). I've done this before and it's not too bad.
That said, `pselect`, `ppoll`, and others do make it doable. Just setup your handlers and mask all your signals. Unmask them when calling `ppoll` or `pselect`, and use non-blocking fd's for everything so none of your other calls like `recv` can block. In general this is one of the recommend ways to do things anyway even without considering handling signals.
The author also has a bit of a misunderstanding of how to use `pselect` and similar calls in the small addendum - it's not necessary for libraries like ZeroMQ to expose a `precv` call as long as they expose access to the underlying fd (or fd's) that makeup the connection. The whole idea is that if `pselect` or similar returns that data is ready in that particular `fd`, the call to `recv` should not block and thus you don't have a problem. This is obviously true when using non-blocking fd's (It won't block ever, even without using `pselect` first), it's is less true when not using them (Through it is still better then nothing. The calls will only block if you request more data then is available in the buffer).
- moefh 9y ago> will only block if you request more data then is available in the buffer Sadly, that's not true on Linux. According to the man page[1]: > Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. (I assume the same is true of pselect(), described in the same page, although it doesn't specifically say so) So the rule is: don't trust select(), always use O_NONBLOCK if you don't want to block. [1] http://man7.org/linux/man-pages/man2/select.2.html http://man7.org/linux/man-pages/man2/select.2.html
- DSMan195276 9y agoHuh, that's interesting. That seems weird to me, but I suppose it could technically make things faster assuming things like checksum failures are rare. I suppose the reason might be that they can mark the socket while still in the interrupt handler, but I haven't read those parts of the kernel close enough to know if they actually do such a thing. But either way, I would agree, if you don't want blocking then just use O_NONBLOCK, it's the intended way and it's the best way.
- zokier 9y ago> Signals are definitely a pain point on Unix - they're decently easy to implement on the OS side, but you just have to think there was a better way. I imagine kqueue would be one of the better ways?
- DSMan195276 9y agoYes, I don't know tons about it but in general kqueue looks like a good solution, and like what I would want for a generic solution (Though obviously, kqueue goes beyond just signals, and might be a little bit complicated when talking about a solution just for signals). My thinking is more along the lines that signals are literally just user-land interrupts, and it would have been nice if they went for something other then that so that you don't have to worry about user-land code being interrupted, and all the ugliness that follows that. But I suppose it's worth keeping in mind that the first Unix didn't feature O_NONBLOCK or `select`, and the syscalls had to be cancel-able, so there is only so much they could do. And signal handlers help avoid having to call some conditional check after every syscall. But I fell like having something similar to `signalfd` that was a standard fd (STDSIGNAL_FILENO I suppose) from the start would have been nicer overall.