Linux System Programming · intermediate · ~10 min

kill() — sending a signal to another process

Send signals between processes with kill() — safely, locally, and only to processes you own.

Lesson

What kill() really does

kill(pid, signo) sends a signal to another process. Despite its name, it is not only about terminating processes. It is a general-purpose way to signal them.

Common uses:

  • SIGUSR1 — tell a process to do something custom, such as reload its configuration.
  • SIGTERM — politely ask a process to exit.
  • Signal 0 — send no signal at all, just probe whether the pid still exists. If the process is gone, kill() fails with ESRCH.

Who is allowed to signal whom

On Linux, you may signal a process if either of these is true:

  • You are root.
  • Your real or effective uid matches the target's real or saved uid.

uid = user ID, the number the system uses to identify the account a process belongs to.

The practical result: a normal user can only signal their own processes, never another user's.

An ethical note

This lesson is about signalling cooperating processes:

  • a child you spawned,
  • a daemon you wrote,
  • a test fixture you control.

Do not go hunting for arbitrary pids on a shared machine.

Code examples

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(void) {
    pid_t child = fork();
    if (child == 0) {
        /* child: wait for a signal */
        pause();
        printf("child got woken up\n");
        return 0;
    }
    sleep(1);
    kill(child, SIGUSR1);     /* SIGUSR1 default = terminate */
    /* In a real program, the child would handle SIGUSR1 cleanly. */
    return 0;
}

Common mistakes

  • Misreading kill(pid, 0). It does not send a signal. It only checks whether the signal could be delivered. This is handy for asking "is this pid still alive?", but it is easy to misread as actually sending something.
  • The pid-reuse race. After a process exits, the operating system can reuse its pid for a completely different process. Always send signals to a pid you spawned yourself and have not yet reaped.

Summary

  • kill(pid, signo) sends a signal to another process; it is general-purpose signalling, not just termination.
  • Use signal 0 to probe whether a pid still exists (you get ESRCH if it is gone).
  • You can only signal processes you own (matching uid), unless you are root.
  • Beware pid reuse: only signal pids you spawned and have not reaped.

Practice with these exercises