软中断1 --- 信号

目录

1. 信号的基本

1.1 信号的特点

1.2 信号的默认行为

1.3 常见的信号

1.4 信号的处理

2. 信号的注册

2.1 signal

2.2 sigaction

3. 四种情形

4. 信号的阻塞

4.1 忽略和阻塞

4.2 sigaction实现局部阻塞

4.3 sigprocmask实现全局阻塞

4.4 查看阻塞的信号

5. kill信号

6. 计时器

6.1 分类

6.2 实现


1. 信号的基本

1.1 信号的特点

  • 信号是消息的载体
  • 信号是一种软中断

1.2 信号的默认行为

term --- 终止一个进程

ign --- 忽略

core --- 终止进程,产生core文件

stop --- 停止一个进程

con --- 继续运行

1.3 常见的信号

SIGINT(2)        ---   term   ---   ctrl+C

SIGQUIT(3)      ---   core   ---   ctrl+\

SIGKILL(9)       ---   term

SIGSEGV(11)   ---   core   ---   访问无效内存

SIGPIPE(13)     ---   term   ---   写一个读端关闭的通道

SIGALRM(14)   ---   term   ---    时钟信号

SIGUSR1(10)    ---   term   ---   用户自定义

SIGUSR2(12)    ---   term   ---   用户自定义   

1.4 信号的处理

默认处理:以默认方式处理。

忽略:进程继续运行,忽略对信号的处理。

捕捉信号并处理:进程实现定义信号处理函数,接收到信号时由函数自动捕捉并处理。

2. 信号的注册

2.1 signal

//信号处理函数
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
//handler:结构体指针,指向信号处理函数
//成功返回结构体指针,失败返回SIG_ERR

2.2 sigaction

可移植性更强

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
//act:结构体指针,指向处理信号的结构体
//结构体
struct sigaction {
               //旧类型的信号处理函数
               void     (*sa_handler)(int);
               //新类型的信号处理函数
                 //siginfo_t指向siginfo_t结构体,结构体存储详细的信号信息
                 //void*指向ucontext_t结构体,结构体包含内核保存在用户空间上信号的上下文信息
               void     (*sa_sigaction)(int, siginfo_t *, void *);
               sigset_t   sa_mask;
               int        sa_flags;
               void     (*sa_restorer)(void);
           };
//恢复系统调用
act.sa_flags = SA_RESETHAND

NOTICE: 若同时使用新旧类型,会优先使用最后调用的类型。

理由:新旧类型是一个联合体

struct sigaction {
	union {
	__sighandler_t _sa_handler;
	void (*_sa_sigaction)(int, struct siginfo *, void *);
	} _u;
	sigset_t sa_mask;
	unsigned long sa_flags;
	void (*sa_restorer)(void);
};

3. 四种情形

情形一:处理完一个信号,是否需要重新注册捕捉下一个信号 --- 不需要

情形二:信号处理过程中收到一个同类型的信号 --- 只会多执行一次,忽略其他信号

情形三:信号处理过程中收到一个不同类型的信号 --- 立即处理,且后续相同类型的信号只会处理

               一次,完成后再处理原信号

情形四:进程正阻塞在系统调用上,此时收到一个信号

               --- 对signal,会优先处理信号的行为,再重新阻塞

               --- 对sigaction,会优先处理信号的行为,不会继续阻塞,系统调用返回失败

4. 信号的阻塞

4.1 忽略和阻塞

  • 忽略:不作任何处理
  • 阻塞:不会立即处理,过一段时间再执行

4.2 sigaction实现局部阻塞

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
//set:保存阻塞信号的集合
sigset_t set;
sigempty(&set);
sigaddset(&set,SIGNAL);
act.sa_mask = set;

4.3 sigprocmask实现全局阻塞

int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
//how: 处理方式 --- SIG_BLOCK | SIG_UNBLOCK | SIG_SETMASK
//set:存储需要阻塞的信号的集合
//可设置阻塞范围,实现全局阻塞

4.4 查看阻塞的信号

//查看系统中阻塞的信号
int sigpending(sigset_t *set);
//判断信号是否在集合中
int sigismember(const sigset_t *set, int signum);
//在集合中返回1,不在返回0,失返回-1

5. kill信号

NOTICE: 9和19号信号无法被捕捉!

int kill(pid_t pid, int sig);
//pid > 0 --- 给pid指的进程发送信号
//pid = 0 --- 给包括调用进程在内的同组的每一个进程发送信号
//pid = -1 --- 广播信号,给系统中除init和自己外的所有进程发送信号
//pid < -1 --- 向gid == |pid|的进程组的所有下属进程发送信号

6. 计时器

6.1 分类

  • 真实计时器:计算从程序启动到当前时刻实际运行的时间 SIGALRM
  • 虚拟计时器:计算程序在用户态消耗的是时间(不包含系统调用及睡眠时间)SIGVTALRM
  • 实用计时器:计算程序在用户态及内核态消耗的时间 SIGPROF

6.2 实现

int getitimer(int which, struct itimerval *curr_value);
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
//which:使用的计时器种类 --- ITIMER_REAL | ITIMER_VIRTUAL | ITIMER_PROF
//curr_value:指向itimerval结构体,该结构体保存计时器相关信息
struct itimerval{
    struct timeval it_interval;   //重复间隔时间
    struct timeval it_value;      //初始间隔
}; 
struct timeval{
    time_t      tv_sec;
    suseconds_t tv_usec;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值