2 ms·
> Is there even a way to correctly deal with signals in the first place? There is, but it requires a level of rigor and overhead that tends to make them poor c
by ajross 3y ago
> Is there even a way to correctly deal with signals in the first place?
There is, but it requires a level of rigor and overhead that tends to make them poor choices for practical engineering. Signals are, at their core, 1:1 isomorphic to interrupts being delivered to a physical CPU. The stop execution and transfer it to a different location at an arbitrary/uncontrollable time. Operating systems deal with this problem robustly all the time, they have to.
What you typically do as the fundamental building block is provide some way of "masking" the interrupts (e.g. sigaction() with appropriate flags for every signal you might receive) so that they won't occur while you're inspecting some critical state. On hardware this is generally cheap, but with signals it's a whole system call (or many, if there are multiple signals to deal with). So generally this isn't the common technique.
So you fall back to the other OS technique, typically used for non-maskable interrupts: don't touch anything. You can't call OS APIs safely (because they might have been preempted in arbitrary states), so you're limited to doing lockless algorithms that can safely update the shared data in a way that can be inspected later. Then maybe you might queue up an "event" or something to get the interrupted context to re-inspect state "soon", etc...
The second option generally is what unix processes try to do. Except that it's really hard (because it's isomorphic to lockless coding!), and easy to get wrong. So signals ended up with the reuptation of being fundamentally broken.
They're not. They have a home and can be used robustly. Just... don't, unless you really really need them for some reason.