raise(sig) is the simplest way for a process to send a signal to itself. In a single-threaded program it is exactly equivalent to kill(getpid(), sig).
In a multithreaded program there is a subtle difference: raise(sig) delivers the signal to the specific thread that called it, while kill(getpid(), sig) delivers to any thread in the process.
One important behaviour: when a process sends a signal to itself using raise(), the signal is delivered immediately β before raise() returns.
| Feature | raise(sig) | kill(getpid(), sig) |
|---|---|---|
| Single-threaded | Identical behaviour | Identical behaviour |
| Multithreaded | Signal delivered to calling thread | Signal delivered to any thread |
| C standard? | Yes (C89) | POSIX only (needs process IDs) |
| Delivery timing | Immediate (before return) | Immediate (before return) |
/* raise() β send a signal to the calling process
Compile: gcc -o raise_demo raise_demo.c
Run: ./raise_demo */
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
static void handler(int sig)
{
write(1, "Handler called via raise()\n", 27);
}
int main(void)
{
/* Install handler for SIGUSR1 */
signal(SIGUSR1, handler);
printf("About to call raise(SIGUSR1)...\n");
raise(SIGUSR1); /* signal delivered before this returns */
/* This line runs AFTER the handler returns */
printf("Back in main() after raise(). Handler already ran.\n");
/* raise(SIGTERM) β no handler, default = terminate */
printf("Now raising SIGTERM β process will terminate.\n");
raise(SIGTERM);
/* Never reached */
printf("This never prints.\n");
return 0;
}
killpg(pgrp, sig) sends a signal to all processes in the process group with ID pgrp. It is exactly equivalent to kill(-pgrp, sig).
#include <signal.h>
int killpg(pid_t pgrp, int sig);
/* Returns 0 on success, -1 on error */
If pgrp is 0, the signal is sent to all processes in the caller’s own process group.
/* killpg() β signal a process group
Compile: gcc -o killpg_demo killpg_demo.c
Run: ./killpg_demo */
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
int main(void)
{
pid_t my_pgid = getpgrp();
printf("My PID=%d, PGID=%d\n", getpid(), (int)my_pgid);
printf("Sending SIGUSR1 to my process group...\n");
/* This is the same as kill(-my_pgid, SIGUSR1) */
if (killpg(my_pgid, SIGUSR1) == -1)
perror("killpg");
else
printf("SIGUSR1 sent to process group %d\n", (int)my_pgid);
return 0;
}
/* Use raise(SIGABRT) to produce a core dump on assertion failure
Compile: gcc -o assert_demo assert_demo.c
Run: ./assert_demo */
#include <stdio.h>
#include <signal.h>
/* Custom assertion macro using raise() */
#define MY_ASSERT(expr) \
do { \
if (!(expr)) { \
fprintf(stderr, "Assertion failed: %s " \
"at line %d\n", #expr, __LINE__);\
raise(SIGABRT); /* produces core dump */\
} \
} while (0)
int main(void)
{
int x = 5;
int y = 0;
MY_ASSERT(x > 0); /* passes */
printf("First assertion passed.\n");
MY_ASSERT(y != 0); /* fails β triggers SIGABRT β core dump */
printf("This never prints.\n");
return 0;
}
strsignal(), psignal() and sys_siglist β Printing human-readable signal descriptions
