part5 linux中的信号

linux中的信号

什么是信号

信号的目的:用来通信

信号是异步的(对比硬件中断)

信号本质上是int型数字编号(事先定义好的)

信号由谁发出

用户在终端按下按键

硬件异常后由OS内核发送信号

用户使用kill命令向其他进程发送信号

某种软件条件满足后也会发送信号,如alarm闹钟时间到会产生SIGALARM信号,向一个读端已经关闭的管道write时会产生SIGPIPE信号

信号由谁处理、如何处理

三种处理方式

忽略信号

捕获信号(进程的信号执行函数)

默认处理(进程没有明显的管理这个信号,默认:忽略或者终止进程)

常见信号介绍

在/usr/include/x86_64-linux-gnu/bits$ 里的signum.h文件里面

                                       编号

SIGINT                             2                Ctril+C时OS给前台进程组中每个进程
SIGABRT                         6                调用abort函数,进程异常终止
SIGPOLL    SIGIO           8                 指示一个异步IO事件,在高级IO中             
SIGKILL                           9                 杀死进程的终极方法
SIGSEGV                       11                无效存储访问时OS发出该信号(数组越界返回的警告信息)
SIGPIPE                         13                涉及异步通信的管道和socket
SIGALARM                    14                 设计alarm函数(闹钟功能)的实现
SIGTERM                      15                 kill命令发送的OS默认终止信号
SIGCHLD                       17                子进程终止或停止时OS向其父进程发送此信号

 
SIGUSR1                        10               用户自定义信号,作用与意义自己定义
SIGUSR2                        12                

进程对信号的处理

signal函数

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void func(int sig)
{
    if(SIGINT != sig)
        return;
    printf("\nfunc for signal: %d.\n",sig);
}

int main(void)
{
    signal(SIGINT, func);//收到SIGINT信号后会执行这个函数。

    return 0;
}

用signal函数处理SIGINT信号

默认处理

忽略处理

捕获处理

signal函数绑定一个捕获函数后,信号发生后会自动执行绑定捕获函数,并将信号编号作为传参传给捕获函数

signal函数的返回值在出错时为SIG_ERR;绑定成功时返回旧的捕获函数

signal函数的有点和缺点

优点:简单好用,捕获信号常用

缺点:无法简单直接得知之前设置的对信号的处理方式

sigaction函数

与signal函数相比具有较好的可移植性。

用法关键:两个sigaction指针

sigaction可以一次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数)

alarm和pause函数

alarm函数

内核以API形式提供的闹钟

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void func(int sig)
{
    if(SIGALRM == sig)
    {
        printf("alarm happened.\n");
    }
}
int main()
{
    unsigned int ret = -1;
    struct sigaction act = {0};
    act.sa_handler = func;
    //signal(SIGALRM, func);
    sigaction(SIGALRM, &act, NULL);
    ret = alarm(3);
    while(1);
    printf("ret = %d.\n", ret);
    return 0;
}
 

pause函数

内核挂起

作用:进程暂停运行,交出CPU给其他进程执行,当当前进程进入pause状态后当前进程就会表现为“阻塞”,退出pause状态当前进程需要被信号唤醒。

使用alarm和pause来模拟sleep

void mysleep(unsigned int sec)
{
    struct sigaction act = {0};
    act.sa_handler = func;
    sigaction(SIGALRM, &act, NULL);
    alarm(sec);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值