3-3 信号的概念、认识、处理动作

一:信号的基本概念

进程之间的常用通信手段:发送信号,kill 第二章第二节讲过;
上节讨论过 SIGHUP
信号 :通知(事情通知),用来通知某个进程发生了某一个事情;
事情,信号都是突发事件, 信号是异步发生的,信号也被称呼为“软件中断”

信号如何产生:
a)某个进程发送给另外一个进程或者发送给自己;
b)由内核(操作系统)发送给某个进程
b.1)通过在键盘输入命令ctrl+c[中断信号],kill命令
b.2)内存访问异常,除数为0等等,硬件都会检测到并且通知内核;

信号名字,都是以SIG开头,上节课SIGHUP(终端断开信号)
UNIX以及类(类似)UNIX操作系统(linux,freebsd,solaris);支持的信号数量各不相同。10-60多个之间;

信号既有名字,其实也都是一些数字,信号是一些正整数常量;信号就是宏定义(数字,从1开始)
#include <signal.h>(/usr/include/)
gcc 编译
头文件,包含路径:/user/local/include/ /usr/include/
库文件,连接路径:/usr/ local/lib/ /usr/lib

//sudo find / -name "signal.h" | xargs grep -in "SIGHUP"

二:通过kill命令认识一些信号

kill :kill 进程id ,他的工作是发个信号给进程;
kill能给进程发送多种信号;
ps -eo pid,ppid,sid,tty,pgrp,comm | grep -E ‘bash|PID|nginx’
sudo strace -e trace=signal -p 1184

a)如果你单纯的用kill 进程id,那么就是往 进程发送SIGTERM信号(终止信号)
kill -数字 进程id,能发出跟这个数字对应的信号 -1 进程id,SIGHUP信号去

b)如果我门用kill -1 进程id,那么就是往进程nginx发送SIGHUP终止信号;同时进程nginx就被终止掉了;
c)kill -2 进程id,发送SIGINT信号;
kill -数字 进程id ,能发送出多种信号;
kill 命令不同数字所能发出的不同信号:
在这里插入图片描述

三:进程的状态

ps -eo pid,ppid,sid,tty,pgrp,comm,stat | grep -E ‘bash|PID|nginx’
ps aux | grep -E ‘bash|PID|nginx’ //aux所谓BSD风格显示格式;
kill只是发个信号,而不是单纯的杀死的意思。
在这里插入图片描述

四:常用的信号列举

在这里插入图片描述
在这里插入图片描述

五:信号处理的相关动作

当某个信号出现时,我们可以按三种方式之一进行处理,我们称之为信号的处理或者与信号相关的动作;
(1)执行系统默认动作 ,绝大多数信号的默认动作是杀死你这个进程;
(2)忽略此信号(但是不包括SIGKILL和SIGSTOP)
//signal(SIGHUP,SIG_IGN); 我收到这个信号后,请操作系统不要干掉我;
kill -9 进程id,是一定能够把这个进程杀掉的;
(3)捕捉该信号:我写个处理函数,信号来的时候,我就用处理函数来处理;(但是不包括SIGKILL和SIGSTOP)

signal() 函数

C++ 信号处理库提供了 signal 函数,用来捕获突发事件。以下是 signal() 函数的语法:

void (*signal (int sig, void (*func)(int)))(int); 

这个函数接收两个参数:第一个参数是一个整数,代表了信号的编号;第二个参数是一个指向信号处理函数的指针。

让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理程序相关联。看看下面的实例:

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum )
{
    cout << "Interrupt signal (" << signum << ") received.\n";

    // 清理并关闭
    // 终止程序  

   exit(signum);  

}

int main ()
{
    // 注册信号 SIGINT 和信号处理程序
    signal(SIGINT, signalHandler);  

    while(1){
       cout << "Going to sleep...." << endl;
       sleep(1);
    }

    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Going to sleep…
Going to sleep…
Going to sleep…
现在,按 Ctrl+C 来中断程序,您会看到程序捕获信号,程序打印如下内容并退出:

Going to sleep…
Going to sleep…
Going to sleep…
Interrupt signal (2) received.

raise() 函数

您可以使用函数 raise() 生成信号,该函数带有一个整数信号编号作为参数,语法如下:

int raise (signal sig);

在这里,sig 是要发送的信号的编号,这些信号包括:SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。以下是我们使用 raise() 函数内部生成信号的实例:

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum )
{
    cout << "Interrupt signal (" << signum << ") received.\n";

    // 清理并关闭
    // 终止程序 

   exit(signum);  

}

int main ()
{
    int i = 0;
    // 注册信号 SIGINT 和信号处理程序
    signal(SIGINT, signalHandler);  

    while(++i){
       cout << "Going to sleep...." << endl;
       if( i == 3 ){
          raise( SIGINT);
       }
       sleep(1);
    }

    return 0;
}

当上面的代码被编译和执行时,它会产生下列结果,并会自动退出:

Going to sleep…
Going to sleep…
Going to sleep…
Interrupt signal (2) received.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一门linux下c++通讯架构实战课程,针对c/c++语言已经掌握的很熟并希望进一步深造以将来用c++在linux下从事网络通讯领域/网络服务器的开发和架构工作。这门课程学习难度颇高但也有着极其优渥的薪水(最少30K月薪,最高可达60-80K月薪),这门课程,会先从nginx源码的分析和讲解开始,逐步开始书写属于自己的高性能服务器框架代码,完善个人代码库,这些,将会是您日后能取得高薪的重要筹码。本课程原计划带着大家逐行写代码,但因为代码实在过于复杂和精细,带着写代码可能会造成每节课至少要4~5小时的超长时间,所以老师会在课前先写好代码,主要的时间花费在逐行讲解这些代码上,这一点望同学们周知。如果你觉得非要老师领着写代码才行的话,老师会觉得你当前可能学习本门课程会比较吃力,请不要购买本课程,以免听不懂课程并给老师差评,差评也会非常影响老师课程的销售并造成其他同学的误解。 这门课程要求您具备下面的技能:(1)对c/c++语言掌握的非常熟练,语言本身已经不是继续学习的障碍,并不要求您一定熟悉网络或者linux;(2)对网络通讯架构领域有兴趣、勇于挑战这个高难度的开发领域并期望用大量的付出换取高薪;在这门课程中,实现了一个完整的项目,其中包括通讯框架和业务逻辑框架,浓缩总结起来包括如下几点:(1)项目本身是一个极完整的多线程高并发的服务器程序;(2)按照包头包体格式正确的接收客户端发送过来的数据包, 完美解决收包时的数据粘包问题;(3)根据收到的包的不同来执行不同的业务处理逻辑;(4)把业务处理产生的结果数据包正确返回给客户端;本项目用到的主要开发技术和特色包括:(1)epoll高并发通讯技术,用到的触发模式是epoll中的水平触发模式【LT】;(2)自己写了一套线程池来处理业务逻辑,调用适当的业务逻辑处理函数处理业务并返回给客户端处理结果;(3)线程之间的同步技术包括互斥量,信号量等等;(4)连接池中连接的延迟回收技术,这是整个项目中的精华技术,极大程度上消除诸多导致服务器程序工作不稳定的因素;(5)专门处理数据发送的一整套数据发送逻辑以及对应的发送线程;(6)其他次要技术,包括信号、日志打印、fork()子进程、守护进程等等;

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值