信号源
1、硬件
2、软件
查看系统有哪些信号
kill -l
进程收到信号的三种响应:
1、忽略信号 不能忽略 SIGKILL、SIGSTOP
2、捕获并处理 (自定义) 不能捕获 SIGKILL、SIGSTOP
3、缺省处理 缺省处理到底执行什么动作,详见 man 7 signal
安装信号(注册信号)
void(*signal(int signo, void (*handler)(int)) )(int);
//从左到右找第一个不是关键字的
//参数:signo 要注册的信号 handler 信号处理函数
/*
define SIG_IGN((sighandler_t*)(1)) :忽略
define SIG_DFL((sighandler_t*)(0)) :缺省
define SIG_ERR((sighandler_t*)(-1)) :返回错误
*/
//signal(SIGIN, SIG_IGN)
//返回值: 旧的信号处理
信号分类
1、可靠信号和不可靠信号
不可靠表现在:
1)当执行完信号处理函数后,恢复成缺省处理动作
2) 当多个信号同时抵达,可能出现信号丢失
1-31 :不可靠
34-64: 可靠
2、实时信号和非实时信号
实时信号都是可靠信号
非实时信号都是不可靠信号
发送信号(kill 命令)
int kill(pid_t pid, // 给那个进程发送信号
int signal); // 发送什么信号
/*pid :
>0 发送给指定的进程
=0 发送本进程组任何一个信号
=-1 发送给本进程有权发送的任何一个进程
<-1 发送给|pid|进程组的任何一个进程
*/
SIGALRM
int alarm(int set);
//set : 过了set这么多秒,信号SIGALRM抵达
// 0 清除
setitimer函数
setitimer( int which, const struct itimerrval *val, struct timeval *old); //定时器
//which :ITIMER_REAL
/*struct itimerval {
struct timeval it_interval; /* next value */ //以后每次间隔时间
struct timeval it_value; /* current value */ //第一次启动时间
};
*/
/* struct timeval {
time_t tv_sec; /* seconds */ 秒
suseconds_t tv_usec; /* microseconds */ 微秒
};
*/
超时问题
SIGCHLD 当子进程变成僵尸进程,系统会给父进程发送这个信号
signal(SIGCHLD,STG_IGN);// SIGCHLD 缺省是忽略,但不会将僵尸进程处理掉,我们将捕获并告诉系统SIG_IGN ,子进程死亡,不会出现僵尸
可重入和不可重入函数
如果函数内部:
- 操纵静态变量
- 调用了malloc/free,因为malloc使用全局链表来管理的
- 使用标准IO
就是不可重入函数
可重入函数:可以被任意打断
信号的内核表示
递达:执行信号处理动作称为信号的递达(delivery)
从信号的产生到信号的递达之间的状态称为未决(pending)
进程可以阻塞(block)信号,被阻塞信号产生时,一直处于未决状态,直到该进程解除对该信号的阻塞,才执行该动作。
//清空信号集
int sigemptyset(sigset_t *set);
//填充
int sigfillset(sigset *set);
//将某一个信号加入信号集
int sigaddset(sigset _t*set, int signum);
//将某一信号从信号集中删除
int sigdeiset(sigset _t*set, int signum);
//判断某一个信号是否在信号集中
int sigismember(const sigset_t *set, int signum)
sigprocmask 信号阻塞(信号屏蔽)
int sigprocmask(int how, const sigset_t *set , sigset_t *old);
/*how :
SIG_BLOCK : mask =mask|(*set)
SIG_UNBLOCK: mask=mask&(~set)
SIG_SETMASK: mask =*set
*/
//返回值:成功为0,出错为1
获取信号内核的未决状态集
int sigpenfding(sigset_t *t)
竞态 : 跟时间有关的错误
int pause(void); //将当前进程挂起,转存储调度,直到有信号抵达,才唤醒该进程
for(; ;)
pause();
int sleep()
{
}
int signsuspend(const sigset_t *set);
//等价于pause+信号屏蔽
int sigaction(int signo,
struct signaction *set, //设置信号处理
struct signaction *old) //返回旧的信号处理
/*struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask; //信号处理函数执行期间的信号屏蔽
int sa_flags; // 0
};
*/
//volatile : 保持内存可见性
相关代码
这里写代码片