我们知道系统调用一旦阻塞,当信号到来是会中断此系统调用执行的,但是如下情况是不会对系统调用产生影响:
1.单个进程阻塞信号不会对后续系统调用产生中断行为。
2.线程中通过pthread_sigmask阻塞信号后,对该进程发送的信号是不影响该线程的系统调用的,会被发送到其他线程处理。
对于阻塞的信号,相当于是延后处理,改为unblock后,会立即触发信号行为。如果一直处于阻塞状态,那么相当于忽略。
多线程的示例如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <pthread.h>
#include "include/debug.h"
void *thr_fn(void *arg)
{
int err, signo;
sigset_t mask;
sigfillset(&mask);
for (;;) {
err = sigwait(&mask, &signo);
if (err != 0) {
err_exit("sigwait failed\n");
}
switch (signo) {
case SIGTERM:
pr_info("Catch SIGTERM; exiting\n");
break;
case SIGQUIT:
pr_info("Catch SIGQUIT; exiting\n");
exit(0);
break;
case SIGINT:
pr_info("Catch SIGINT; exiting\n");
break;
default:
pr_info("Unexpected signal %d\n", signo);
}
}
return(0);
}
pthread_t setup_signal_thread(void)
{
int err;
struct sigaction sa;
sigset_t mask;
pthread_t tid;
/*
* Block all signals in main thread
*/
sigfillset(&mask);
if ((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)
err_exit("SIG_BLOCK error\n");
/*
* Create a child thread to handle SIGHUP and SIGTERM.
*/
err = pthread_create(&tid, NULL, thr_fn, 0);
if (err != 0)
err_exit("can't create thread\n");
return tid;
}
int main()
{
char buf[10];
pthread_t tid;
void *tret;
tid = setup_signal_thread();
read(STDIN_FILENO, buf, 10);
printf("read was interrupted!\n");
}
测试结果:
xiehaocheng@xiehaocheng:~/work/qemu/sdk/test/linuxc$ ./syscall_intr
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting
^C[604] INFO: Catch SIGINT; exiting