As far as I understood your question you want to signal a process by its name, not by its PID. This can easily be achieved by combining the two commands:
kill -s signal $(ps -C executable)
Does it kill the process that signals?
kill can kill. It doesn't necessarily.
From man kill:
The command kill sends the specified signal to the specified processes or process groups.
That means, the kill command is used to **send any signal in general.
If it kills a process it means that it's similar to do
exit(0), or does the process resume after the signal is sent back?
From here:
The
SIGKILLsignal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.
If a process receives the SIGKILL signal, it terminates immediately (no destructors called, no cleanup done). The only processes that do not terminate are uninterruptible processes.
A full list of signals available on Linux is found here.
Answer from cadaniluk on Stack OverflowAs far as I understood your question you want to signal a process by its name, not by its PID. This can easily be achieved by combining the two commands:
kill -s signal $(ps -C executable)
Does it kill the process that signals?
kill can kill. It doesn't necessarily.
From man kill:
The command kill sends the specified signal to the specified processes or process groups.
That means, the kill command is used to **send any signal in general.
If it kills a process it means that it's similar to do
exit(0), or does the process resume after the signal is sent back?
From here:
The
SIGKILLsignal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.
If a process receives the SIGKILL signal, it terminates immediately (no destructors called, no cleanup done). The only processes that do not terminate are uninterruptible processes.
A full list of signals available on Linux is found here.
I prefer this:
pkill -signal processname
Here is a concrete example I use from time to time:
pkill -USR1 Squeak
See pkill - Wikipedia
Videos
A signal handler is just a function within a given process' address space. This function is executed whenever the signal is received. There's nothing special about it (although there are certain actions that should not be performed within a signal handler), and it does not reside in a special thread.
While signals are often described as being software interrupts, they aren't actually asynchronous.* When a signal is sent to a process, the kernel adds it to the process' pending signal set. It doesn't cause anything to happen immediately. The signal will only actually do anything at the next context switch back to userspace (whether that's a syscall returning or the scheduler switching to that process). If a process were to, for whatever reason, never switch from kernel to user, the signal would be kept in the pending signal set and never acted upon.† This is why some processors can get stuck doing I/O ("uninterruptable sleep") and are seemingly unkillable, even with SIGKILL.
When a process establishes a signal handler, it gives the kernel an address to a function. When the process is to receive a signal, the next context switch from kernelspace to userspace will not restore the execution context from before the process entered the kernel (usually, the context is saved when entering the kernel and restored upon exiting it). Instead, it will "restore" execution at the location of the signal handler. The signal handler doesn't return to where it was called from, but to a piece of code called a trampoline which then calls rt_sigreturn(), which restores the real execution context, allowing the process to continue where it left off.‡
When a process has multiple threads (i.e. there are multiple processes in a given thread group), the signal is sent to one of the threads in the thread group at random. This is because threads typically share memory and many other resources and run the same code.
The execution of a signal handler is described in more detail in signal(7). Whenever there is a transition from kernel to user and there is a pending unblocked signal, the following steps occur:
(1) The kernel performs the necessary preparatory steps for execution of the signal handler: (1.1) The signal is removed from the set of pending signals. (1.2) If the signal handler was installed by a call to sigaction(2) that specified the SA_ONSTACK flag and the thread has defined an alternate signal stack (using sigaltstack(2)), then that stack is installed. (1.3) Various pieces of signal-related context are saved into a special frame that is created on the stack. The saved information includes: • the program counter register (i.e., the address of the next instruction in the main program that should be executed when the signal handler returns); • architecture-specific register state required for resuming the interrupted program; • the thread's current signal mask; • the thread's alternate signal stack settings. If the signal handler was installed using the sigaction(2) SA_SIGINFO flag, then the above information is accessible via the ucontext_t object that is pointed to by the third argument of the signal handler. This object reflects the state at which the signal is delivered, rather than in the handler; for example, the mask of blocked signals stored in this object will not contain the mask of new signals blocked through sigaction(2). (1.4) Any signals specified in act->sa_mask when registering the handler with sigaction(2) are added to the thread's signal mask. The signal being delivered is also added to the signal mask, unless SA_NODEFER was specified when registering the handler. These signals are thus blocked while the handler executes. (2) The kernel constructs a frame for the signal handler on the stack. The kernel sets the program counter for the thread to point to the first instruction of the signal handler function, and configures the return address for that function to point to a piece of user-space code known as the signal trampoline (described in sigreturn(2)). (3) The kernel passes control back to user-space, where execution commences at the start of the signal handler function. (4) When the signal handler returns, control passes to the signal trampoline code. (5) The signal trampoline calls sigreturn(2), a system call that uses the information in the stack frame created in step 1 to restore the thread to its state before the signal handler was called. The thread's signal mask and alternate signal stack settings are restored as part of this procedure. Upon completion of the call to sigreturn(2), the kernel transfers control back to user space, and the thread recommences execution at the point where it was interrupted by the signal handler.
* While they aren't asynchronous from the perspective of hardware, they are effectively asynchronous as far as userspace applications are concerned. This is why they are sometimes called software interrupts.
† When I refer to context switches, I mean privilege or process switches (i.e. both simple mode transitions between kernel and user within the same process and "true" context switches between processes or kernel threads).
‡ On some Unix systems, the kernel passes control to the trampoline first, not the signal handler. The trampoline calls the signal handler and then, once it returns, sigreturn().
The interrupt handler (signal handler) is not the process thread, nor any thread running under that process, correct?
The kernel doesn't start a new thread to execute a signal handler. It executes the signal handler on an existing thread. We could say that the signal is delivered to that particular thread. Basically, the thread drops whatever it was doing before, and executes the signal handler. After the signal handler returns, it goes back to what it was doing before. (forest's answer goes into more detail about how exactly the kernel schedules this.) But a key difference between this and an ordinary function call is that you don't have control over when it happens. So for example, on a platform where 32-bit accesses are atomic and 64-bit accesses are not, it's possible that the thread is in the middle of writing to a int64_t variable when the signal handler invocation occurs. Therefore, even in a single-threaded program, the signal handler must guard against "the thread racing against itself", so to speak. Consequently, the set of operations you can perform safely inside a signal handler is very limited.
The sender of a signal can choose to send it to a particular thread, for example by calling tgkill, or target an entire process. When a signal is sent to a process, the kernel selects one of the threads in the process to deliver it to. See What happens to a multithreaded Linux process if it gets a signal?
Note that if the behaviour of the signal is to terminate the recipient (e.g. SIGKILL, or SIGTERM with the default handler) then the entire process terminates even if you direct it at a particular thread.