文章目录

  • 1、信号的基本概念
  • 2、两个信号捕获函数
    • 2.1、signal信号函数
    • 2.2、sigaction函数
    • 2.3、信号相关函数
  • 3、两个时钟函数
    • 3.1、alarm函数
    • 3.2、setitimer函数
  • 4、信号作用
  • 5、可重入函数

1、信号的基本概念

1、 信号(signal)是软件中断,是进程之间相互传递信息的一种方法,用于通知进程发送了的事件,但是,不能给进程传递任何数据
2、信号产生的原因有很多,在Linux下,可以用kill和killall命令发送信号

ps -ef | grep 需要查询的程序
kill 跟随的是进程号
killall 程序名

一共有64个信号,每个信号对应自己的默认动作


进程状态表

信号名  信号值 默认处理动作  发出信号的原因
SIGHUP  1   A   终端挂起或者控制进程终止
SIGINT  2   A   键盘中断Ctrl+c
SIGQUIT 3   C   键盘的退出键被按下
SIGILL  4   C   非法指令
SIGABRT 6   C   由abort(3)发出的退出指令
SIGFPE  8   C   浮点异常
SIGKILL 9   AEF 采用kill -9 进程编号 强制杀死程序。
SIGSEGV 11  C   无效的内存引用
SIGPIPE 13  A   管道破裂,写一个没有读端口的管道。
SIGALRM 14  A   由alarm(2)发出的信号
SIGTERM 15  A   采用“kill 进程编号”或“killall 程序名”通知程序。
SIGUSR1 10  A   用户自定义信号1
SIGUSR2 12  A   用户自定义信号2
SIGCHLD 17  B   子进程结束信号
SIGCONT 18      进程继续(曾被停止的进程)
SIGSTOP 19  DEF 终止进程
SIGTSTP 20  D   控制终端(tty)上按下停止键
SIGTTIN 21  D   后台进程企图从控制终端读
SIGTTOU 22  D   后台进程企图从控制终端写处理动作一项中的字母含义如下:
A 缺省的动作是终止进程。
B 缺省的动作是忽略此信号,将该信号丢弃,不做处理。
C 缺省的动作是终止进程并进行内核映像转储(core dump),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员 提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。
D 缺省的动作是停止进程,进入停止状态的程序还能重新继续,一般是在调试的过程中。
E 信号不能被捕获。
F 信号不能被忽略。

2、两个信号捕获函数

2.1、signal信号函数

// 函数指针:返回值void,有一个int参数
typedef void (*sighandler_t)(int);// 主要用于捕获信号,交给回调函数处理
sighandler_t signal(int signo,sighandler_t handler);
参数:signo 信号编号handler 回调函数(返回值void参数为int的函数类型)
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>void func(int sig)
{printf("成功捕获%d信号\n",sig);
}int main()
{// 捕获所有信号,只要有信号来就调回调函数,也可以指定特定信号for(int i=1;i<=64;i++)signal(i,func);while(1){printf("执行一次任务。\n");sleep(1);}return 0;
}
    // 忽略信号signal(SIGTERM,SIG_IGN);//还原成系统缺损的动作signal(SIGTERM,SIG_DFL);

2.2、sigaction函数

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
参数:signum 信号编号act 默认需要初始化结构体oldact 旧的结构体(一步不使用可以传NULL)返回值:成功 0失败 -1
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>void sys_perror(const char* str)
{perror(str);exit(1);
}void cat_sig(int signo)
{printf("hello world %d\n",signo);
}int main()
{struct sigaction act,oldact;act.sa_handler = cat_sig; // 设置信号捕捉函数sigemptyset(&(act.sa_mask));    // 设置信号捕捉期间maskact.sa_flags = 0;   // 设置默认属性int ret = sigaction(SIGINT,&act,&oldact);if(ret == -1)sys_perror("sigaction error");// signal(SIGINT,cat_sig);while(1);return 0;
}

2.3、信号相关函数

sigemptyset()    把信号集中所有信号都置为0,表示所有信号都没有来
sigfillset()    把信号集中所有信号都置为1,
sigaddset()     增加信号,把某个信号从0变成1
sigdelset()     删除信号,把某个信号从1变成0
sigprocmask()   设置信号集中的内容
sigismember()       测试当前信号在信号集中是否为1返回true
SIG_BLOCK:
按照参数  set 提供的屏蔽字,屏蔽信号。并将原信号屏蔽保存到oldset中。
SIG_UNBLOCK:
按照参数  set 提供的屏蔽字进行信号的解除屏蔽。针对Set中的信号进行解屏。
SIG_SETMASK:
按照参数  set 提供的信号设置重新设置系统信号设置。一个进程会对应一个信号集,用来记录阻塞了哪些信号,如果把这个信号集中的某个信号位设置位1,
此时在来同类信号就会阻塞
#include <iostream>
#include <signal.h>
#include <unistd.h>
using namespace std;void mysignal(int sig)
{printf("信号:%d\n",sig);signal(sig,SIG_DFL);    // 执行一次后,恢复默认行为
}int main()
{sigset_t newsig,oldsig;signal(SIGQUIT,mysignal);       // 注册信号回调函数sigemptyset(&newsig);           // 将newsig信号集中所有信号设置为0sigaddset(&newsig,SIGQUIT);     // 将newsig信号集中的SIGQUIT信号设置为1// 设置当前进程的信号集// 第一个参数SIG_BLOCK表示设置进程新的信号屏蔽字(当前信号和第二个的并集)// 信号集// 不为空,则保存信号之前的信号集sigprocmask(SIG_BLOCK,&newsig,&oldsig); sleep(5);if(sigismember(&newsig,SIGQUIT))    // 测试当前信号的信号集是否是1{printf("SIGQUIT信号已经被屏蔽\n");}if(sigismember(&newsig,SIGHUP))    // 测试当前信号的信号集是否是1{printf("SIGHUP信号已经被屏蔽\n");}sigprocmask(SIG_SETMASK,&oldsig,NULL);if(sigismember(&oldsig,SIGQUIT))    // 测试当前信号的信号集是否是1{printf("SIGQUIT信号已经被屏蔽\n");}else{printf("当前SIGQUIT已解除屏蔽\n");}sleep(5);printf("结束\n");return 0;
}

3、两个时钟函数

3.1、alarm函数

(定时发送SIGALRM给当前进程,默认动作为终止进程,只会执行一次)

unsigned int alarm(unsigned int seconds);
参数:seconds 定时秒数
返回值:上次定时闹钟剩余时间无错误现象

SIGALRM信号默认动作是终止进程,现在我们捕获了这个进程,然后用自定义函数处理

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>void alarmfunc(int sig)
{printf("接收到了时钟信号%d\n",sig);
}int main()
{signal(SIGALRM,alarmfunc);alarm(3);while(1){printf("执行一次任务。\n");sleep(1);}return 0;
}

3.2、setitimer函数

(定时发送SIGALRM给当前进程,默认动作为终止进程)

int setitimer(int which,const struct itimerval* new_value,struct itimerval* old_value);
参数:which ITIMER_REAL (14 SIGLARM) 自然时间ITIMER_VIRTUAL(26 SIGVTALRM) 虚拟空间时间(只计算进程占用cpu的时间)ITIMER_PROF (27 SIGPROF) 运行时计时(用户+内核,)new_value 定时秒数it_interval:用来设定两次定时任务之间间隔的时间it_value:定时的时长old_value 上次定时闹钟剩余秒数
返回值:成功 0失败 -1
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>void sys_perror(const char* str)
{perror(str);exit(1);
}int main()
{   // 参数初始化struct itimerval it,oldit;it.it_value.tv_sec = 1;    // 设置秒说it.it_value.tv_usec = 0;it.it_interval.tv_sec = 0;  // 设置间隔为0秒it.it_interval.tv_usec = 0;// 错误检查if(setitimer(ITIMER_REAL,&it,&oldit) == -1) sys_perror("setitimer error");int i=1;while (i++){printf("%d\n",i);}return 0;
}

4、信号作用

服务程序运行在后台,如果想让终止它,直接杀掉,不是很好,因为程序突然死亡,很多工作没有处理,如果想服务程序发送一个信号,服务程序收到这个信号后,调用一个函数,在函数中编写善后代码,程序就可以有计划的退出,向服务程序发送0的信号,可以检测释放存活

5、可重入函数

所谓可重入函数:就是我们在信号处理函数中,调用是安全的,这些函数是可重入的并称为异步信号安全的。
如果必须要在信号处理函数中调用那些可能修改errno值的可重入的系统函数,就需要事先备份,然后在信号函数尾部给他恢复回去。

Linux C 信号使用相关推荐

  1. linux kill信号列表

    linux kill信号列表 $ kill -l 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL 5) SIGTRAP      6 ...

  2. linux多线程信号总结

    linux多线程信号总结-businiaowyf-ChinaUnix博客 linux 多线程信号处理总结 - CobbLiu - 博客园

  3. linux python 信号,Python模块之信号(signal)

    在了解了Linux的信号基础之 后,Python标准库中的signal包就很容易学习和理解.signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时 ...

  4. linux 查看进程的信号,Linux 进程信号查看与控制

    Linux 进程信号查看与控制 1) SIGHUP 本信号在用户终端连接 (正常或非正常) 结束时发出 通常是在终端的控制进程结束时 通知同一 session 内的各个作业 这时它们与控制终端不再关联 ...

  5. Linux进程间通信——信号

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  6. Linux进程信号(产生、保存、处理)/可重入函数概念/volatile理解/SIGCHLD信号

    首先区分一下Linux信号跟进程间通信中的信号量,它们的关系就犹如老婆跟老婆饼一样,没有一毛钱的关系. 信号的概念 信号的概念:信号是进程之间事件异步通知的一种方式,属于软中断.比如:红绿灯是一种信号 ...

  7. Linux Signal信号详解

    信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全 ...

  8. linux. qt信号崩溃,【创龙AM4379 Cortex-A9试用体验】之I/O中断异步通知驱动程序+QT捕获Linux系统信号+测试信号通知...

    2.驱动程序 安装字符设备驱动程序开发流程开发. 2.1资源定义 定义按键I/O端口号.I/O中断号,以及字符设备的主设备号变量: #define GPIO_KEY1_PIN_NUM (3*32 + ...

  9. Linux系统信号定义

    Linux系统信号,即signal,定义通常在这个头文件中: /usr/include/asm-generic/signal.h 常见的信号如下: #define SIGHUP         1 # ...

  10. linux操作系统---信号

    linux操作系统---信号 信号 定义 信号的响应方式 修改信号的响应方式 注意事项 练习 信号的发送 练习 信号 定义 系统预先定义好的某些特定的事件,信号可以被发送,也可以被接受,发送和接受的主 ...

最新文章

  1. linux php-fpm启动失败,linux运行php-fpm遇到问题
  2. Git 代码防丢指南
  3. 查看mysql 默认端口号和修改端口号
  4. c语言释放整个链表,最简单的链表删除第一个节点时释放内存的问题
  5. Content-Disposition 响应头,设置文件在浏览器打开还是下载
  6. 如何用Java创建不可变的Map
  7. Deep Glow for mac(AE高级辉光特效插件)支持ae2021
  8. 教师节快乐:删了库之后,不要着急跑路
  9. java生成一条唯一的邀请码_根据用户id生成一个唯一邀请码
  10. mybatis 新增语句_mybatis增删改查
  11. 使用原生Java代码生成可执行Jar包
  12. 自旋锁原理及java自旋锁
  13. php支持微信h5支付,PHP接入微信H5支付的方法示例
  14. 雄迈摄像头研究笔记一:telnet的开启
  15. 台式电脑硬件维修操作规范
  16. 用户授权中@Secured,@PreAuthorize,@PostAuthorize,@PreFilter,@PostFilter这五个注解的使用
  17. 编译《视觉SLAM十四讲》ch5里joinmap出现 ***/anaconda3/lib/libpng16.so.16:‘inflateValidate@ZLIB_1.2.9’未定义的引用
  18. 如何更高好地管理待办事项?
  19. idea出现 淇℃伅 乱码
  20. message from server: Host 'DESKTOP-QIR7OV5' is not allowed to connect to this MySQL server问题

热门文章

  1. 良品铺子三只松鼠财报之争:网红零食里的“冰火两重天”
  2. Oracle日志文件中状态为INVALID(原因分析)
  3. 阿里云redis大key搜索工具
  4. Python画图-中使用plt生成的图的legend,设置字体大小
  5. css样式详解及覆盖顺序
  6. 站点地图-SiteMap
  7. UE4中的Actor、Pawn和Character
  8. illustrator插件--常用功能开发--绘制手提袋--js脚本开发--AI插件
  9. 创建和调用存储过程:查询Stu数据库中某个同学的选修课程的信息,包括学号,姓名,课程名称,成绩
  10. 爱了一个不该爱的人...