信号的处理:在合适的时机
组合键只能发消息给前台
信号处理:默认处理:大部分终止进程,自定义处理:signal,捕捉信号,忽略。
信号本身不重要,针对信号做出响应比较重要。
信号产生:键盘,系统命令:软,硬件:段错误。
信号处理叫抵达,产生到抵达叫未决
信号和进程息息相关,组织信号示意图在PCB:代码,数据,信号
变量先定义,再使用
Makefile的另一种书写方式
bin=my_signal
src=my_signal.c
cc=gcc
$(bin):$(src)
$(cc) -o $@ $^
.PHONY:clean
clean:
rm -f my_signal
信号类函数:
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);(增加一个信号至信号集),sigaddset()用来将参数signum 代表的信号加入至参数set 信号集里。 返回值 执行成功则返回0,如果有错误则返回-1。
int sigdelset(sigset_t *set, int signum);
int sigismember(const sigset_t *set, int signum);
int sigprocmask(int how,const sigset_t *set,sigset_t * oldset);
sigprocmask()可以用来改变目前的信号遮罩,其操作依参数how来决定
SIG_BLOCK 新的信号遮罩由目前的信号遮罩和参数set 指定的信号遮罩作联集
SIG_UNBLOCK 将目前的信号遮罩删除掉参数set指定的信号遮罩
SIG_SETMASK 将目前的信号遮罩设成参数set指定的信号遮罩。
如果参数oldset不是NULL指针,那么目前的信号遮罩会由此指针返回。
执行成功则返回0,如果有错误则返回-1。
#include<stdio.h> #include<signal.h> #include<sys/types.h> #include<stdlib.h> int main() { int count=0; while(count<5){ count++; sleep(1); } //kill(getpid(),11); //raise(11); abort(); return 0; } //阻塞是种状态,未决是有无 void show(sigset_t* sig) { int i=1; for(;i<32;++i) { if(sigismember(sig,i)) printf("1"); else printf("0"); } printf("\n"); } int main() { sigset_t sig_mask; sigset_t sig_old; sigset_t sig_pending; sigemptyset(&sig_mask); sigemptyset(&sig_old); sigemptyset(&sig_pending); sigaddset(&sig_mask,2); sigprocmask(SIG_SETMASK,&sig_mask,&sig_old); while(1) { sigpending(&sig_pending); show(&sig_pending); sleep(1); } return 0; }
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。
unsigned int alarm(unsigned int seconds);
它的主要功能是设置信号传送闹钟。其主要功能用来设置信号SIGALRM在经过seconds指定的秒数后传送给目前的进程,如果在定时未完成的时间内再次调用了alarm函数,则后一次定时器设置将覆盖前面的设置,当seconds设置为0时,定时器将被取消。它返回上次定时器剩余时间,如果是第一次设置则返回0。
#include<stdio.h> #include<signal.h> #include<string.h> void handler(int sig) { //do nothing } int my_sleep(int time) { struct sigaction act; act.sa_handler=handler; act.sa_flags=0; sigemptyset(&act.sa_mask); struct sigaction old; memset(&old,'\0',sizeof(old)); sigaction(SIGALRM,&act,&old);//注册信号处理函数 alarm(time);//time秒后让系统发SIGALRM信号 pause();//内核切换到别的进程运行 int ret=alarm(0); sigaction(SIGALRM,&old,NULL);//恢复默认信号处理动作 return ret; } int main() { while(1) { printf("I am sleep...\n"); my_sleep(5); } return 0; }