The select(2), poll(2), and epoll(7) system calls are just a way to wait for events on file descriptors (small integers representing an I/O channel). Events can include "data read for read", "ready to write", things like that. Your code makes up a set of file descriptors that will eventually have an event, and then calls select(), or poll() or epoll() to cause the program to wait until data arrives, the kernel connects the socket to some other host, a descriptor had an error, whatever.
signalfd(2) adds a new event: a signal has arrived. In unix/linux/*BSD a "signal" is a more-or-less asynchronous event: CPU tried to execute an illegal instruction, I/O is ready, code divided by zero, the modem hung up. signalfd(2) lets you create a file descriptor, usable in select(), poll(), epoll(), that has an event when a signal arrives.
In the past, you would specify a handler function, which the kernel magically called when a signal arrives (a.k.a. an "upcall"). If you used the sigaction() system call to tell the kernel what function you wanted it to call, you got the same information that sigwaitinfo() can get you.
The difference between setting a handler function with signal() or sigaction() over signalfd() is that the handler function could get magically called at any time: parts of your code had to be re-entrant (not just thread-safe, mind you) to deal with the "at any time" nature of signals. With signalfd(), a signal is just another event to deal with in your code's event loop. Your code just executes as usual.
sigwaitinfo() causes your code to pause until and when a signal you specified arrives. Your code does nothing until that signal arrives. No event loop, no nothing. It also looks like sigwaitinfo() is part of the real time stuff in the Linux kernel. sigwaitinfo() could be thought of as designating a spot in the code for the kernel to call when a signal arrives, rather than designating a function to call.
Addition:
I've just discovered a blog post sbout the "self pipe trick". Apparently not only is it inconvenient code-wise to handle signals and select-based I/O, you can also suffer "nasty race conditions". The self pipe trick gets around that by doing essentially what signalfd(2) does, but all in user space, and at a cost of more code.
^C
send the interrupt signal, which can be handled by a program (you can ignore it)
kill -9
send the sigkill signal which kills the program that you can't handle.
That's why you can't kill some programs with ^C
Best Answer
kill -INT $pid
sends the "interrupt" signal to the process with process IDpid
. However, the process may decide to ignore the signal, or catch the signal and do something before exiting and/or ignore it.kill -9 $pid
sends the "kill" signal which cannot be caught or ignored. The process will be forcibly shut down with no notification to the process, and no chance to do any cleanup what so ever.kill -9 $pid
should almost never be recommended or used, though sometimes it's necessary.Advanced Concepts
kill -INT $pid
is the same askill -2 $pid
.kill -9 $pid
is the same askill -KILL $pid
There are many versions of the
kill
command. Most shells (ksh, bash, dash, etc) have built-inkill
commands, and there's also one in/bin/kill
. They are all slightly different but most of them support the above examples.Most kill commands have a
-l
or-L
option to list the signals:A good place to read about signals is the "signal" man page in section 7 of the manual:
man 7 signal
.