信号就是一个整数。
linux操作系统的信号共有64个。
32个 不可重用信号 有固定含义
32个 可重复 可设置意义
linux操作系统的信号共有64个。
32个 不可重用信号 有固定含义
32个 可重复 可设置意义
信号发送者:信号源
shell kernel 进程 硬件驱动程序
信号接收者:
shell kernel 进程 硬件驱动程序
shell kernel 进程 硬件驱动程序
信号接收者:
shell kernel 进程 硬件驱动程序
接收到信号后:每个信号定义了一种含义,接收到信号后会自动做对应的操作。
可以自定义信号处理。
信号处理注册函数:signal
注册了一个信号后,进程会接收信号,并用进程设定的信号处理函数取代其原本的对应操作。
函数指针变量:保存了一个函数的地址的指针变量。
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(
int signum,//信号
sighandler_t handler);//信号处理函数
int signum,//信号
sighandler_t handler);//信号处理函数
signal函数可以让进程捕获注册了的信号,并用自定义的函数来设置对信号的反馈。
一个信号只能注册一次,只能有一个信号处理函数去处理这个信号的反馈。
一个信号处理函数可以作为多个信号的反馈处理。
中断,当一个信号处理函数被调用时,会中断调用信号处理函数的进程,等信号处理函数返回后再继续进程。
发送信号:
kill命令
kill函数
kill命令
kill函数
#include <stdio.h>
#include <signal.h>
void hand(int s){
int i;
if(s == 2){
printf("想杀我,你还嫩了点~~~~~~~\n");
for(i=0;i<20;i++){
sleep(1);
printf("hand:%d\n",i);
}
}else if(s == 3)
printf("换了高手啊,还是杀不死我!\n");
else if(s == 28)
printf("^o^\n");
}
int main(){
int n = 1;
signal(2,hand);
signal(3,hand);
signal(28,hand);
printf("%d\n",getpid());
while(1){
printf("我还活得好好的:%d!\n",n++);
sleep(1);
}
return 0;
}
如果希望进程不被某些信号中断,屏蔽某些信号。
sigprocmask signal process mask
sigprocmask signal process mask
int sigprocmask(
int how,//行为
const sigset_t *set, //用来设置哪些信号需要屏蔽
sigset_t *oldset);//保存被屏蔽的信号
int how,//行为
const sigset_t *set, //用来设置哪些信号需要屏蔽
sigset_t *oldset);//保存被屏蔽的信号
信号集:保存多个信号的数组。
信号集操作函数
int sigemptyset(//清空信号集
sigset_t *set);
int sigfillset(//把所有信号填入信号集中
sigset_t *set);
信号集操作函数
int sigemptyset(//清空信号集
sigset_t *set);
int sigfillset(//把所有信号填入信号集中
sigset_t *set);
int sigaddset(//把signum信号加入信号集中
sigset_t *set,
int signum);
sigset_t *set,
int signum);
int sigdelset(//把signum从信号集中移除
sigset_t *set,
int signum);
sigset_t *set,
int signum);
int sigismember(//测试signum是否在信号集中
const sigset_t *set,
int signum);
const sigset_t *set,
int signum);
信号屏蔽只是忽略信号的处理,进程还是接收到了信号,等到解除屏蔽后再处理。
然后不会保存接收信号的次数,只是保存最后一次接收。
然后不会保存接收信号的次数,只是保存最后一次接收。
#include <stdio.h>
#include <signal.h>
void hand(int s){
int i;
if(s == 2){
for(i=0;i<20;i++){
printf("哈哈:%d\n",i);
sleep(1);
}
}else{
printf("hand:%d\n",s);
}
}
int main(){
struct sigaction act = {0};
sigset_t set;
sigaddset(&set,3);
act.sa_handler = hand;
act.sa_mask = set;
signal(3,hand);
sigaction(2,&act,NULL);
while(1){
printf("-----------------------\n");
sleep(1);
}
return 0;
}
高级信号注册函数:sigaction
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);
}
signal在接收信号的时候不能接收其他信息。
sigaction可以使用高级的信号处理函数,在处理信号的时候接收信息。
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);
}
signal在接收信号的时候不能接收其他信息。
sigaction可以使用高级的信号处理函数,在处理信号的时候接收信息。
SA_SIGINFO : 使用高级的信号处理函数,接收信号之外的其他数据
#include <stdio.h>
#include <signal.h>
void hand(int s){
printf("接收到信号%d\n",s);
}
int main(){
int i;
sigset_t set;//定义一个信号集set
sigset_t o_set;
sigfillset(&set);//把所有信号加入信号集中
signal(2,hand);
for(i=0;i<100;i++){
if(i == 10)
sigprocmask(SIG_BLOCK,&set,&o_set);
if(i == 50)
sigprocmask(SIG_UNBLOCK,&set,NULL);
printf("go on:i = %d\n",i);
sleep(1);
}
return 0;
}