信号的介绍及使用

1.什么是信号
(1)信号是内容受限制的一种异步通信机制
(2)信号的目的是用来通信
(3)信号是异步的(对比硬件中断)
(4)信号本质上是int型数字编号(事先定义好的)

2.信号由谁发出
(1)用户在终端按下按键
(2)硬件异常后由操作系统内核发出信号
(3)用户使用kill命令向其他进程发送信号
(4)某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向一个读端已经关闭的管道write时会产生SIGPIPE信号

3.信号由谁处理、如何处理
(1)忽略信号
(2)捕捉信号(信号绑定了一个函数)
(3)默认处理(忽略或终止进程)

4.常见的信号介绍

(1)SIGINT 		2 		Ctrl+c时os送给前台进程组中每个进程
(2)SIGABRT		6		调用abort函数,进程异常终止
(3)SIGPOLL SIGIO 8		指示一个异步IO事件,在高级IO中用到
(4)SIGKILL		9		杀死进程的终极方法
(5)SIGGSEGV	11		无效访问储存时OS发出该信号
(6)SIGPIPE		13		涉及管道和socket
(7)SIGALARM	14		涉及alarm函数实现
(8)SIGTERM		15		kill命令发送的OS默认终止信号
(9)SIGCHLD		17		子进程终止或停止时OS向其父进程发此信号
(10)SIGUSR1		10		用户自定义信号,作用和意义由应用者自己定义
(11)SIGUSR2		12	

5.进程对信号的处理
(1)signal函数的介绍

typedef void (*sighandler_t)(int);	//函数指针
sighandler_t signal(int signum, sighandler_t handler);
参数1:注册一个信号处理方法
参数2:用一个函数来处理
返回值:返回值出错时为SIG_ERR,绑定成功返回旧的捕获函数

(2)用signal函数处理SIGINT信号
(2.1)默认处理(SIG_DFL)
(2.2)忽略处理(SIG_IGN)
(2.3)捕获处理(signal函数绑定一个捕获函数后信号发生后会自动执行绑定的捕获函数,并且把信号编号作为参数传给捕获函数)

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

typedef void (*sighandler_t)(int);

//捕获函数
void func(int sig)
{
        if(SIGINT != sig)
        {
                return;
        }
        printf("func for signal: %d\n",sig);
}

int main(void)
{
        sighandler_t ret = (sighandler_t)-2;

        //sighandler_t signal(int signum, sighandler_t handler);函数原型
        //signal(SIGINT,func);
        //signal(SIGINT,SIG_DFL);       //让信号默认处理
        ret = signal(SIGINT,SIG_IGN);   //忽略处理
        //ret = signal(SIGKILL,SIG_IGN);
        printf("返回值为:%d\n",(int)ret);
        if(SIG_ERR == ret)      //判断信号处理是否成功
        {
                perror("signal");
                exit(-1);
        }
        printf("before while(1)\n");
        while(1);
        printf("after while(1)\n");

        return 0;
}

6.signal函数的缺点和优点
(1)优点:简单好用,捕获信号常用
(2)缺点:无法简单直接得知之前设置的对信号的处理方法,可移植性差(当自己设置捕获函数时就无法移植)

7.sigaction函数介绍

int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
参数1:和signal一样
参数2:设置新的捕获函数
参数3:返回旧的捕获函数

(1)比signal更具有可移植性
(2)用法关键是2个sigaction指针
(3)sigaction可以一次得到(单独)设置新捕获函数和获取旧的捕获函数(要获取哪一个捕获函数设另一个为NULL)

8.alarm函数
(1)内核以API形式提供的闹钟
(2)编程实战

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

void func(int sig)
{
        if(sig == SIGALRM)
        {
                printf("alarm happend\n");
        }
}

int main(void)
{
        unsigned int ret = -1;
        struct sigaction act = {0};

        act.sa_handler = func;

        //int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);函数原型
        sigaction(SIGALRM,&act,NULL);
        //signal(SIGALRM,func);//可以替换sigaction
        ret = alarm(5);//第一次调用alarm返回值是0
        printf("1st ret = %d\n",ret);
        sleep(3);

        ret = alarm(5);//返回值是2但是本次alarm会重新定5s
        printf("2st ret = %d\n",ret);
        sleep(1);

        ret = alarm(5);//返回值是4依然重新定时5s
        printf("3st ret = %d\n",ret);

        while(1);
        return 0;
}

9.pause函数
(1)内核挂起
(2)作用就是让当前进程暂停运行,交出CPU给其他进程去执行,当当前进程进入pause状态后当前进程表象为被卡住、阻塞住,要退出pause状态当前进程需要被信号唤醒。

10.使用alarm和pause来模拟sleep

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

void func(int sig)
{

}

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

        alarm(sec);
        pause();
}

int main(void)
{
        printf("before mysleep\n");
        mysleep(3);
        printf("after mysleep\n");
        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值