尽管这个问题非常古老,但它今天仍然存在。基本上,为了正确关闭临时文件、终止线程等,可以使用以下逻辑:
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;
}
基本上,在信号管理器中,设置了一个
sig_atomic_t
标志,它保证对该变量的原子访问,并使用
volatile
来向编译器发出信号,表明该变量不应被优化,因为它可能会遭受意外更改,例如被信号修改。
使用此标志,您可以通过不使用全局变量以安全的方式处理关闭,例如一系列线程的示例。
&errno
对于每个线程是唯一的!但是,我认为由于刚才描述的相同原因,在glibc / NPTL中可能不安全。如果不是这样,我相信这是符合性错误,但它可能是足够罕见的竞争,以便未被检测到... - R.. GitHub STOP HELPING ICE