当前位置: 技术问答>linux和unix
linux signal 信号
来源: 互联网 发布时间:2017-01-12
本文导语: 情景: 1、多个进程,每个进程中注册同一个信号,信号响应函数只做了一件事情: 让进程睡两秒 sleep(2) 2、每个进程中都有频繁的文件操作和网络通信 问题: 当某个进程给其他几个进程发送信号让其睡眠后,会不...
情景:
1、多个进程,每个进程中注册同一个信号,信号响应函数只做了一件事情: 让进程睡两秒 sleep(2)
2、每个进程中都有频繁的文件操作和网络通信
问题:
当某个进程给其他几个进程发送信号让其睡眠后,会不会导致睡眠的进程文件操作或网络通信出错,比如文件只写一半或者网络接收数据失败等问题
这个问题的背景是这样的,在程序中有临时使用root权限的时候,这段时间我想让其他进程停止工作,所以使用上述方法,有没有好的解决方法?
1、多个进程,每个进程中注册同一个信号,信号响应函数只做了一件事情: 让进程睡两秒 sleep(2)
2、每个进程中都有频繁的文件操作和网络通信
问题:
当某个进程给其他几个进程发送信号让其睡眠后,会不会导致睡眠的进程文件操作或网络通信出错,比如文件只写一半或者网络接收数据失败等问题
这个问题的背景是这样的,在程序中有临时使用root权限的时候,这段时间我想让其他进程停止工作,所以使用上述方法,有没有好的解决方法?
|
硬中断确实会中断系统调用的,signal 应该是软中断,软中断会不会中断系统调用呢?
signal会中断系统调用,比如常见的阻塞函数read/write/select。
通过man手册查看函数的错误代码,如果有EINTR,表示该函数会阻塞,而且会有信号中断的可能性。
比如进程A在read文件,想读取1M数据,阻塞时间为1S。
在这1S内,操作系统可能向A发出信号,例如SIGCHILD、SIGINT,
那么A调用的read将失败并返回-1 , errno为EINTR。
而且,A操作的文件会回复到read调用之前的状态,即文件指针偏移、内容等和read之前一样。
所以,即使出错了,也不用担心,因为操作系统会自动回滚。A只需要再read一次就可以了。
如果A调用read总是被中断怎么办?写一个while(1)不断读取就可。
int interruptable_read( int fd , void* buf , int count)
{
while(1)
{
int ret = read( fd , buf , count);
if( (-1==ret) &&( EINTR==errno))
{
continue;
}
else
{
return ret ;
}
}
}
signal会中断系统调用,比如常见的阻塞函数read/write/select。
通过man手册查看函数的错误代码,如果有EINTR,表示该函数会阻塞,而且会有信号中断的可能性。
比如进程A在read文件,想读取1M数据,阻塞时间为1S。
在这1S内,操作系统可能向A发出信号,例如SIGCHILD、SIGINT,
那么A调用的read将失败并返回-1 , errno为EINTR。
而且,A操作的文件会回复到read调用之前的状态,即文件指针偏移、内容等和read之前一样。
所以,即使出错了,也不用担心,因为操作系统会自动回滚。A只需要再read一次就可以了。
如果A调用read总是被中断怎么办?写一个while(1)不断读取就可。
int interruptable_read( int fd , void* buf , int count)
{
while(1)
{
int ret = read( fd , buf , count);
if( (-1==ret) &&( EINTR==errno))
{
continue;
}
else
{
return ret ;
}
}
}
|
看APUE吧。
|
这个应该不会有什么问题吧,系统会考虑到中断服务程序对现有的进程的执行的影响。
保存变量,或者在可能造成影响的地方关中断。
保存变量,或者在可能造成影响的地方关中断。
|
不同的实现有不同的对待信号中断的方法
对于read:
一种是,read返回被中断时读到的数据;一种是,read返回-1,errno被设置为EINTR。
相应地,对于write:
一种是write返回写入的数据量;一种是返回-1,errno被设置为EINTR。
对于read:
一种是,read返回被中断时读到的数据;一种是,read返回-1,errno被设置为EINTR。
相应地,对于write:
一种是write返回写入的数据量;一种是返回-1,errno被设置为EINTR。
|
进行信号处理将会中断系统调用 errno被设置为EINTR 所以1楼5楼是正确的