(四)Linux系统编程之信号

一、信号集

1、信号的状态

  • 产生
  • 未决状态 - 没有被处理
  • 递达 - 信号被处理了
    在这里插入图片描述
    在这里插入图片描述

2、通过man文档查看信号
a.man 7 signal
b.SIGKILL 和 SIGSTOP不能被捕捉、阻塞和忽略

3、概念:阻塞信号集、未决信号集
位于pcb中【内核】
不能直接操作它们

  • 阻塞信号集
    (1)要屏蔽的信号,将某个信号放在阻塞信号集,这个信号就不会被进程处理
    (2)阻塞解除之后,信号被处理
    (不能被处理,则处于未决状态,当将该信号从阻塞信号集中移除,那么对应在未决信号集中的信号就被处理)

  • 未决信号集
    没有被处理的信号的集合
    在这里插入图片描述

自定义信号集合

  • int sigemptyset(sigset_t *set);
    将set集合置空

  • int sigfillset(sigset_t *set);
    将signo信号加入到set集合

  • int sigaddset(sigset_t*set,int signo);
    将signo信号加入到set集合

  • int sigdelset(sigset_t *set,int signo);
    从set集合中移除signo信号

  • int sigismember(const sigset_t *set,int signo);
    判断信号是否存在

sigprocmask 函数
屏蔽and接触信号屏蔽,将自定义信号集设置给阻塞信号集
函数原型:
int sigpromask(int how,const sigset_t *set,sigset_t *oldset);

sigpending – 读取当前进程的未决信号集
函数原型:int sigpending(sigset *set);
参数:set – 内核将未决信号集写入set【传出参数】

二、信号相关函数

1、kill – 发送信号给指定的进程

函数原型:int kill(pid_t pid,int sig);

返回值:
成功:0
失败:-1(ID非法,信号非法,普通用户杀init进程等权级问题),设置errno

函数参数:
(1)sig信号参数:不推荐直接使用数字,应该使用宏名,因为不同的操作系统信号编号可能不同,但名称一致

(2)pid参数:

  • pid>0:发送信号给指定的进程。
  • pid==0:发送信号给与调用kill函数进程属于同一进程组的所有进程
  • pid<-1:取|pid|发给对应进程组
  • pid=-1:发送给进程有权限发送的系统中所有进程

2、raise – 自己给自己发信号

kill(getpid(),SIGKILL);

函数原型:int raise(int sig);

返回值:


3、abort – 给自己发送异常终止信号

函数原型:void abort(void)

没有参数没有返回值,永远不会调用失败


4、闹钟(定时器)

(1) alarm – 设置定时器(每个进程只有一个定时器)

  • 使用的是自然定时法【最准确】
    不受进程状态的影响
  • 函数原型:unsigned int alarm(unsigned int seconds);
    参数:秒
    当时间到达之后,函数发出一个信号SIGALRM
    返回值
    在这里插入图片描述
    意思是第一次设置5秒的时钟alarm(5),然后sleep(2),第二次重置alarm(5),返回3,即告诉你上一个时钟还剩下3秒。

测试电脑1s能数多少个数字?
测试程序运行的时间:time可执行程序

real=用户+内核+损耗
a.损耗来自文件IO操作


(2)setitimer – 定时器,并实现周期性定时
#include <sys/time.h>

函数原型:
int setitimer(int which,//定时法则
const struct itimerval *new_value,
struct itimerval *old_value//NULL
);

(1)which
ITIMER_REAL 自然定时法 – SIGALRM
ITIMER_VIRTUAL 只计算用户区的代码运行所用时间 – SIGVTALRM
ITIMER_PROT 用户+内核的时间 – SIGPROT

(2)new_value 定时器如何设置

(3)old_value 这是一个传出参数,获取上一次设置定时器的信息

struct itimerval{
struct timeval it_interval; //定时器循环周期
struct timeval it_value; //第一次触发定时器的时间
};

struct timeval{
time_t tv_sec; //秒
suseconds_t tv_usec; //微秒
//两个值是相加的关系
};


三、信号捕捉

1、signal函数

  • typedef void (*sighandler_t)(int);
  • sighandler_t signal(int signum,sighandler_t handler);
    //第二个参数是函数地址【回调函数一定使用函数指针】,即上一个函数的名字
    //该函数捕获信号signum,并使用handler对其进行处理

2、sigaction函数
函数原型:
int sigaction(int signum,//捕捉信号
const struct sigaction *act,
struct sigaction *oldact //一般为NULL
);

    struct sigaction{
    	void (*sa_handler)(int); //处理函数
    	
    	void (*sa_sigaction)(int,siginfo_t *,void *);
    	
    	sigset_t sa_mask; 
    	//作用是在信号处理函数执行过程种,临时屏蔽指定的信号,会自动解除屏蔽,之后该信号即将被处理,可不用(清空操作sigemptyset)
    	
    	int sa_flags;
    	//0 - sa_handler 【使用sa_handler时赋值为0】
    	
    	void (*sa_restorer)(void);
    	//已被废弃了
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值