Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The best thing you can do is set a global variable value and that’s it. Let your main even loop mind the value and proceed from there. Only do this in a single thread and block singles in all others as the first thing you do. Threads and signals do not mix otherwise.

Another option is to use a proper OS that includes the ability to receive signals as a part of your main event loops: https://man.openbsd.org/kqueue.2#EVFILT_SIGNAL

I believe you can also do something similar with epoll() on Linux but not sure the semantics are quite as nice as kqueue.



You want signalfd, which may optionally fed to epoll or any of the other multiplexing syscalls.

Signalfd can mostly be implemented on any platform using a pipe (if you don't have to mix 32-bit and 64-bit processes, or if you don't need the siginfo payload, or if you read your kernel's documentation enough to figure out which "layout" of the union members is active - this is really hairy). Note however the major caveat of running out of pipe buffer.

A more-reliable alternative is to use an async-signal-safe allocator (e.g. an `mmap` wrapper) to atomically store the payloads, and only use a pipe as a flag for whether there's something to look for.

Of course, none of these mechanisms are useful for naturally synchronous signals, such as the `SIGSEGV` from dereferencing an invalid pointer, so the function-coloring approach still needs to be used.


> Another option is to use a proper OS that includes the ability to receive signals as a part of your main event loops

Every 'nix can do that. Your signal handler just writes a byte to a pipe and your main loop reads the pipe or fifo. The pipe/fifo is your event queue, which your main loop reads.


on Linux you are talking about signalfd. Block all signals and then reading from a signalfd returns one pending blocked signal.


> The best thing you can do is set a global variable value and that’s it.

Seems kinda limiting.

If I've got a slow file download going on in one thread, and my program gets a Ctrl+C signal, waiting for the download to complete before I exit ain't exactly a great user experience.


Use select() or epoll() or kqueue() to see if your socket is ready for reading. That way you can monitor your global variable too. That’s the correct way to do it.

If you have multiple threads, you start one just to mind signals.

Signal handlers are extremely limited in what they can do, that’s the point. They are analogous to hardware interrupt handlers.


Why would you not periodically check the value between calls to read() or select()?

Just make sure it's non-blocking or with a relatively short timeout.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: