Despite the very old question the problem still exists today.
Basically to close temporary files, terminate threads correctly, etc. for example, this logic could be used:
volatile sig_atomic_t sig_received = 0;
void sigterm_handler(int signum)
{
printf("SIGTERM. PID: %d\n", getpid());
sig_received = 1;
}
void sigint_handler(int signum)
{
fprintf(stderr, "SIGINT. PID: %d\n", getpid());
}
...
int main()
{
struct sigaction action;
action.sa_handler = sigterm_handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
sigaction(SIGTERM, &action, NULL);
action.sa_handler = sigint_handler;
sigaction(SIGINT, &action, NULL);
pthread_t writer_thread, reader_thread;
struct master_argv writer_args, reader_args;
buffer_init(&(writer_args.buffer));
buffer_init(&(reader_args.buffer));
writer_args.pipename = PIPE_CAPOSC;
reader_args.pipename = PIPE_CAPOLET;
if (pthread_create(&writer_thread, NULL, master, (void *)&writer_args) != 0)
{
exit(1);
}
if (pthread_create(&reader_thread, NULL, master, (void *)&reader_args) != 0)
{
exit(1);
}
while (!sig_received)
{
sleep(1);
}
pthread_join(writer_thread, NULL);
pthread_join(reader_thread, NULL);
buffer_destroy(&(writer_args.buffer));
buffer_destroy(&(reader_args.buffer));
return 0;
}
Basically, within the signal manager, a sig_atomic_t
flag is set which guarantees atomic access to this variable and volatile
to signal to the compiler that this variable must not be optimized since it could undergo unexpected changes such as the modification by a signal .
Using this flag you can handle the closure, in the example of a series of threads, in a safe way by not using global variables