当前位置: 首页 > news >正文

《LINUX系统编程》笔记p7

信号

常见信号

  • 程序段错误
  • kill 杀死进程
  • Ctrl + C 结束进程
  • Ctrl + Z 停止进程

kill 命令

# 查看所有的信号
kill -l
kill -<信号> pid

Linux 中全部的信号

 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX	

UNIX 预定义的信号 (1 ~ 31),以SIG开头

实时信号 (34 ~ 64),以SIGRT开头.

信号默认的5种行为(man 7 signal)

  1. Term 默认终止进程
  2. Ign 默认忽略信号
  3. Core 默认终止进程并产生一个dump文件
  4. Stop 默认停止进程
  5. Cont 默认停止的进程继续运行

两个不能改变默认行为的信号

  • SIGKILL
  • SIGSTOP

前台进程组能接收的三个信号

  1. 中断字符 Ctrl + C, 发出 SIGINT信号
  2. 退出字符 Ctrl + \,发出 SIGQUIT信号
  3. 挂起字符(停止)Ctrl + Z发出 SIGTSTP信号

signal 函数

作用:注册新的信号处理函数,返回旧的信号处理函数。
一个信号只能有一个信号处理函数生效

#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t  signal(int  signum, sighandler_t han‐dler);

handle 参数的取值

  • SIG_IGN. 忽略信号
  • SIG_DFL 信号原本缺省的操作
  • SIG_ERR 报错。

信号处理函数

void sig_handle(int sig);
参数:sig 触发的信号的值。

17) SIGCHLD信号应用

子进程状态变化会触发此信号(一般是子进程退出)

使用信号回收子进程资源示例

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>void sig_wait_child(int sig) {pid_t pid;int status;pid = wait(&status);printf("收到信号:%d, pid:%d的子进程退出了\n", sig, pid);
}
int main(int argc, char * argv[]) {signal(SIGCHLD, sig_wait_child);pid_t pid;pid = fork();if (pid == 0) {sleep(10);printf("子进程:%d退出\n", getpid());return 0;}pid = fork();if (pid == 0) {sleep(15);printf("子进程:%d退出\n", getpid());return 0;}
//    int status;
//    pid = wait(&status);while(1) {printf("主进程在做事情...\n");sleep(30);}return 0;
}

主动发信号相关的函数

# 为指定的进程发送信号kill(2)
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);# 向当前进程发送信号raise(3)
#include <signal.h>
int raise(int sig);# 发送信号alarm(2)信号
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
// 参数: seconds 信号延迟的秒数
// 返回值:上一次信号剩余的秒数。

示例:尝试让子进程给 父进程发送 SIGKILL 信号,杀死父进程,子进程继续运行。

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(int argc, char * argv[]) {pid_t pid;int ret;pid = fork();if (pid == 0) {sleep(10);ret = kill(getppid(), SIGKILL);printf("子进程 ret:%d\n", ret);sleep(20);printf("子进程退出\n");return 0;}while(1) {printf("主进程在做事情...\n");sleep(30);}return 0;
}

alarm(2)函数

作用:定时为 当前进程发送 SIGALRM 信号,实现定时器的功能。

示例代码

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>void sig_alarm_handle(int sig) {printf("时间到了:%d\n", sig);alarm(5);// 5秒钟后会收到SIGALRM信号 
}
int main(int argc, char * argv[]) {signal(SIGALRM, sig_alarm_handle);alarm(5);// 5秒钟后会收到SIGALRM信号 while(1) {printf("程序运行中...\n");sleep(10);}return 0;
}

使用信号要注意的问题

  1. 信号处理函数应尽快返回,避免函数内死循环。
  2. 信号会打断程序的睡眠状态。

setitimer(2)函数

作用:实现精准定时和循环定时

#include <sys/time.h>int setitimer(int which, const struct itimerval *new_value,struct itimerval *old_value);
// 参数:whichITIMER_REAL: 系统的真实时钟ITIMER_VIRTUAL: 虚拟时钟,计算用户进程占用CPU 的时间。// struct itimerval {
//     // 闹钟的间隔时间
//     struct timeval it_interval; /* Interval for periodic timer */
//     // 闹钟的启动时间
//     struct timeval it_value;    /* Time until next expiration */
// };
// 
// struct timeval {
//     time_t      tv_sec;         /* seconds */
//     suseconds_t tv_usec;        /* microseconds */
// };

示例

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>void sig_alarm_handle(int sig) {printf("时间到了:%d\n", sig);alarm(5);// 5秒钟后会收到SIGALRM信号 
}
int main(int argc, char * argv[]) {signal(SIGALRM, sig_alarm_handle);// alarm(5);// 5秒钟后会收到SIGALRM信号 struct itimerval itv = {};// 5秒钟后响铃itv.it_value.tv_sec = 5;itv.it_value.tv_usec = 0;// 间隔2.5秒钟后响铃itv.it_interval.tv_sec = 2;itv.it_interval.tv_usec = 500000; // 0.5秒// 设置时间setitimer(ITIMER_REAL, &itv, NULL);while(1)pause(); // 暂停,直至有信号才解除阻塞while(1) {printf("程序运行中...\n");sleep(10);}return 0;
}
http://www.dtcms.com/a/361452.html

相关文章:

  • 1.数值分析——概述、误差
  • 【数据可视化-105】Pyecharts主题组件:让你的图表瞬间高大上
  • c++关键字
  • 首屏优化讲解
  • JavaEE 进阶第一期:开启前端入门之旅(上)
  • pip不是内部或外部命令的问题怎么解决?
  • 【数据库】Sql Server数据库中isnull、iif、case when三种方式的使用和空值判断
  • docker本地部署dify,nginx80端口占用的报错
  • Spring Ioc —— 集合类型的依赖注入
  • js语言编写科技风格博客网站-详细源码
  • LINUX驱动篇(二)驱动开发
  • 埃文科技荣获2025年“数据要素×”大赛河南分赛二等奖
  • FPGA时序约束(二)--做时序约束,本质上是在干嘛
  • 新闻资讯|基于微信小程序的经济新闻资讯系统设计与实现(源码+数据库+文档)
  • ARM-进阶汇编指令
  • 基于AI与物联网的中央空调节能调控系统
  • 原子操作(Atomic Operation) 是指不可被中断的操作——要么完整执行,要么完全不执行
  • Android修改进程优先级
  • 在IDEA里使用Google Java Format
  • UART控制器——ZYNQ学习笔记14
  • 解决Content Security Policy (CSP)问题
  • Sparse4Dv3 部署到 TensorRT-(1)
  • Gradle vs. Maven,Java 构建工具该用哪个?
  • Paimon MergeTreeWrite、Compaction 和 快照构建
  • 嵌入式解谜日志之Linux操作系统—进程间的通信(IPC):无名管道,有名管道,信号通信5
  • 单片机元件学习
  • 【stm32】定时器(超详细)
  • Git安装教程
  • 【51页PPT】智慧社区解决方案(附下载方式)
  • 审美积累 | 金融类 SaaS 产品落地页设计