> Another common extension is to use what is sometimes called a double Ctrl-C pattern. The first time the user hits Ctrl-C, you attempt to shut down the database cleanly, but the second time you encounter it, you give up and exit immediately.
This is a terrible behavior, because users tend to hit Ctrl-C multiple times without intending anything different than on a single hit (not to mention bouncing key mechanics and short key repeat delays). Unclean exits should be reserved for SIGQUIT (Ctrl-\) and SIGKILL (by definition).
If you don't know about it, sure, but I find it's kind of convenient to get a safe shutdown and then be able to easily say "I don't care, just stop this program" without needing a separate kill -9 command or something.
In the Meson build system's test harness, a single Ctrl-C terminates the longest running test with a SIGTERM; while three Ctrl-C in a second interrupt the whole run as if you sent the harness a SIGTERM. This was done because it's not uncommon that there are hundreds of tests left to run and you have seen what you want, and it's useful to have an intuitive shortcut for that case.
However, in both cases it's a clean shutdown, all running are terminated and the test report is printed.
> Unclean exits should be reserved for SIGQUIT (Ctrl-\) and SIGKILL (by definition).
I don't know how it works on your keyboard but on french layout, Ctrl-\ is a two-hands, three-fingers, very unpleasant on the wrist, keyboard shortcut. Not a chance I'd use that for such a common operation.
It's worse, because there are languages that encode interruption into the error handling functionality, so it's common that people mismanage their errors and programs require several Ctrl-C presses to actually reach the interruption handler.
What means that you have to memorize a list of "oh, this program needs Ctrl-C 3 times; oh, this program must only receive Ctrl-C once!"... I don't know of any "oh, this program needs Ctrl-C exactly 2 times", but it's an annoying possibility.
They can print a message that states that it is attempting to quit cleanly but can be forced to quit by pressing Ctrl+C another time(s). Unison does this.
The article doesn't mention the most useful of all signals: SIGINFO, aka "please print to stderr your current status". Very useful for tools like dd and tar.
Probably because Linux doesn't implement it. Worst mistake Linus ever made.
Also, it talks about self-pipe but doesn't mention that self-socket is much better since you can't select on a pipe.
> self-socket is much better since you can't select on a pipe.
This needs further explanation. Why can’t you select on a pipe? You certainly can use select/poll on pipes in general and I’m not sure of any reason in particular they won’t work for the self pipe notification.
Thanks for the feedback! As the talk and the post both mentioned, I was focusing on signals that work on all Unix platforms. Within the constraints of a 30 minute talk there must be material left on the cutting room floor. (If I started talking about the specifics of various Unix lineages I could fill up a whole day...)
For most users in the real world, self-pipes are sufficient. This includes mio (Tokio's underlying library)'s portable Unix implementation of wakers (how parts of the system tell other parts to wake up).
SIGSTOP is the equivalent of Ctrl-Z in a shell, but you can address it to any process. If you have a server being bogged down, you can stop the offending process temporarily.
SIGCONT undoes SIGSTOP.
The cpulimit tool does this in an automated way so that a process can be limited to use x% of CPU. Nice/renice doesn't keep your CPU from hitting 100% even with an idle priority process, which may be undesirable if it drains battery quickly or makes the cooling fan loud.
I recently wrote a little data transfer service in python that runs in ECS. When developing it locally it was easy to handle SIGINT: try write a batch, except KeyboardInterrupt, if caught mark the transfer as incomplete and finally commit the change and shut down.
But there’s no exception in python to catch for a SIGTERM, which is what ECS and other service mangers send when it’s time to shut down. So I had to add a signal handler. Would have been neat if SIGTERM could be caught like SIGINT with a “native” exception.
from signal import SIGTERM, raise_signal, signal
import sys # for excepthook
class Terminate(BaseException):
pass
def _excepthook(type, value, traceback):
if not issubclass(type, Terminate):
return _prevhook(type, value, traceback)
# If a Terminate went unhandled, make sure we are killed
# by SIGTERM as far as wait(2) and friends are concerned.
signal(SIGTERM, _prevterm)
raise_signal(SIGTERM)
_prevhook, sys.excepthook = sys.excepthook, _excepthook
def terminate(signo=SIGTERM, frame=None):
signal(SIGTERM, _prevterm)
raise Terminate
_prevterm = signal(SIGTERM, terminate)
chrsig|1 year ago
Turns out, they use SIGWINCH (which is sent on WINdow CHange) for graceful shutdown.
It's a silly, silly problem.
eadmund|1 year ago
That’s … that’s even worse than people who send errors with an HTTP 200 response code.
thayne|1 year ago
ykonstant|1 year ago
unknown|1 year ago
[deleted]
layer8|1 year ago
This is a terrible behavior, because users tend to hit Ctrl-C multiple times without intending anything different than on a single hit (not to mention bouncing key mechanics and short key repeat delays). Unclean exits should be reserved for SIGQUIT (Ctrl-\) and SIGKILL (by definition).
tripdout|1 year ago
bonzini|1 year ago
However, in both cases it's a clean shutdown, all running are terminated and the test report is printed.
jcelerier|1 year ago
I don't know how it works on your keyboard but on french layout, Ctrl-\ is a two-hands, three-fingers, very unpleasant on the wrist, keyboard shortcut. Not a chance I'd use that for such a common operation.
marcosdumay|1 year ago
What means that you have to memorize a list of "oh, this program needs Ctrl-C 3 times; oh, this program must only receive Ctrl-C once!"... I don't know of any "oh, this program needs Ctrl-C exactly 2 times", but it's an annoying possibility.
bcrl|1 year ago
Levitating|1 year ago
sunshowers|1 year ago
cperciva|1 year ago
Probably because Linux doesn't implement it. Worst mistake Linus ever made.
Also, it talks about self-pipe but doesn't mention that self-socket is much better since you can't select on a pipe.
epcoa|1 year ago
This needs further explanation. Why can’t you select on a pipe? You certainly can use select/poll on pipes in general and I’m not sure of any reason in particular they won’t work for the self pipe notification.
Its even right in the original: https://cr.yp.to/docs/selfpipe.html
sunshowers|1 year ago
For most users in the real world, self-pipes are sufficient. This includes mio (Tokio's underlying library)'s portable Unix implementation of wakers (how parts of the system tell other parts to wake up).
avidiax|1 year ago
SIGSTOP is the equivalent of Ctrl-Z in a shell, but you can address it to any process. If you have a server being bogged down, you can stop the offending process temporarily.
SIGCONT undoes SIGSTOP.
The cpulimit tool does this in an automated way so that a process can be limited to use x% of CPU. Nice/renice doesn't keep your CPU from hitting 100% even with an idle priority process, which may be undesirable if it drains battery quickly or makes the cooling fan loud.
fragmede|1 year ago
efxhoy|1 year ago
But there’s no exception in python to catch for a SIGTERM, which is what ECS and other service mangers send when it’s time to shut down. So I had to add a signal handler. Would have been neat if SIGTERM could be caught like SIGINT with a “native” exception.
mananaysiempre|1 year ago
Spivak|1 year ago
One common pattern is raising KeyboardInterrupt from your handler so it's all handled the same.