I need to send a signal to a process and when the process receives this signal it does some things, how is this best achieved in C?
Asked
Active
Viewed 6.6k times
3 Answers
27
The way to send a signal to a process is kill(pid, signal);
However, you should be aware that signals are not a robust means of inter-process communication except for parent-to-direct-child messages due to inherent race conditions. Pipes, files, directories, named semaphores, sockets, shared memory, etc. all provide greatly superior approaches to inter-process communication.

R.. GitHub STOP HELPING ICE
- 208,859
- 35
- 376
- 711
-
Which header file defines kill? – Koray Tugay Jun 04 '15 at 19:42
-
4It's declared in `
` – R.. GitHub STOP HELPING ICE Jun 04 '15 at 19:52 -
Is it standard C or POSIX? I am confused because wikipedia page for signal.h does not include kill also C in a Nutshell book does not mention this function. – Koray Tugay Jun 04 '15 at 19:52
-
1Plain C does not have processes, so it has no way to a send a signal to a process. In plain C you can signal yourself with `raise`. Processes and the functions to act on them come from POSIX. – R.. GitHub STOP HELPING ICE Jun 05 '15 at 01:41
-
The idea comes to me to send a Signal to `Audacity` while for example browsing on the web recording my voice reading – Salem Apr 21 '22 at 05:41
4
If you happen to be on one of the Unix variants, the following man pages will help:
man 2 kill
man 2 signal
man 2 sigvec

Ronan Boiteau
- 9,608
- 6
- 34
- 56

wildplasser
- 43,142
- 8
- 66
- 109
0
kill
+ fork
runnable POSIX example
Time for some fun:
#define _XOPEN_SOURCE 700
#include <assert.h>
#include <signal.h>
#include <stdbool.h> /* false */
#include <stdio.h> /* perror */
#include <stdlib.h> /* EXIT_SUCCESS, EXIT_FAILURE */
#include <sys/wait.h> /* wait, sleep */
#include <unistd.h> /* fork, write */
void signal_handler(int sig) {
char s1[] = "SIGUSR1\n";
char s2[] = "SIGUSR2\n";
if (sig == SIGUSR1) {
write(STDOUT_FILENO, s1, sizeof(s1));
} else if (sig == SIGUSR2) {
write(STDOUT_FILENO, s2, sizeof(s2));
}
signal(sig, signal_handler);
}
int main() {
pid_t pid;
signal(SIGUSR1, signal_handler);
signal(SIGUSR2, signal_handler);
pid = fork();
if (pid == -1) {
perror("fork");
assert(false);
} else {
if (pid == 0) {
while (1);
exit(EXIT_SUCCESS);
}
while (1) {
kill(pid, SIGUSR1);
sleep(1);
kill(pid, SIGUSR2);
sleep(1);
}
}
return EXIT_SUCCESS;
}
Compile and run:
gcc -std=c99 signal_fork.c
./a.out
Outcome:
SIGUSR1
SIGUSR2
SIGUSR1
SIGUSR2
....
But beware that there are many complexities when dealing with signals:
- only certain functions can be called from signal handlers: Why only async-signal-safe functions can be called from signal handlers safely?
- different functions have different behaviors when interrupted by signals:
man 7 signal
,SA_RESTART
- global variables can only be accessed from the signal handler if they have type
sig_atomic_t
: How does sig_atomic_t actually work?
Tested in Ubuntu 17.10, GitHub upstream.

Ciro Santilli OurBigBook.com
- 347,512
- 102
- 1,199
- 985