linux的SA_RESTART信号

SA_RESTART信号其实就是作用于当我程序进行运行的时候 这个当前的程序处于阻塞状态 比如read当前的STDIN_FILENO 终端输入 时候 这个时候程序处于阻塞状态 等待输入字符串 但是当我用kill指令发送给当前程序时候 这个read函数阻塞状态突然就会被打断 errno会被赋值EINTR 并且这个系统调用read会被返回-1 代表出错了 而且会立即被退出程序abort 中断程序运行

这个原因是因为我发送信号时候 当前进程处于阻塞状态 当前的read函数还没有执行完毕 突然来一个信号 那么我是不是就要立即进行执行信号处理 而且我的这个传送的信号没有被屏蔽 所以当前程序会跳出当前read这个系统调用函数 直接转而进行执行信号处理函数(信号递送) 那么问题来了 不是说如果信号处理完毕会接着执行还没有执行完毕的系统调用么?为什么会突然系统异常终止呢 这个原因就是因为系统会在你执行完信号时候 继续执行当前系统调用时候默认返回-1 errno赋值EINTR 退出程序
所以导致我们有时候莫名其妙的就程序异常终止了 所以为了解决这个慢系统的问题 我们可以通过信号屏蔽 阻塞当前传入的信号
然后通过sigpending去获取未决信号 然后当我们当前信号处理函数执行完毕再接着执行系统调用 但是这个方法不太恰当 我觉得既然系统内部发送和递送信号那么肯定追求的实时性 所以这个方法不恰当 所以重点来了 就是采用讲sigaction结构体的sa_flags赋值SA_RESTART 这个可以让当前进程接着执行没有执行完毕的系统调用函数read 不会默认返回-1 异常终止 网上很多官方的术语其实都是模糊不清 请看下列的例子 这个就是一个很简单而经典的程序 程序不会异常终止 就是因为我在信号处理的信号结构体sigaction 的sa_flags赋值了SA_RESTART

#include
#include
#include
#include
#include
#include
void sig_echo(int signum)
{
if(signum==SIGUSR1)
{

	printf("SIGUSR1 recieve!\n");
	
}
else if(signum==SIGUSR2)
{
	printf("SIGUSR2 recieve!\n");
}
printf("noSIG\n");

}
int main(int argc,char* argv[])
{

struct sigaction sig;
sig.sa_flags=SA_RESTART;
sig.sa_handler=sig_echo;
char buf[1024];
memset(buf,0,sizeof(buf));
sigaction(SIGUSR1,&sig,NULL);
sigaction(SIGUSR2,&sig,NULL);
while(1)
{
	memset(buf,0,sizeof(buf));
	if(read(STDIN_FILENO,buf,sizeof(buf))<0)
	{
		if(errno=EINTR)
		{
			exit(EXIT_FILURE);
			printf("exit error");
		}
	}
	else{
		
		printf("%s\n",buf);
		
	}
	
}






return 0;

}

你可能感兴趣的:(linux的SA_RESTART信号)