【IPC 通信】信号处理接口 Signal API(7)

news/2024/5/19 1:16:22 标签: linux, 信号处理, IPC 通信, signal

         收发信号思想是 Linux 程序设计特性之一,一个信号可以认为是一种软中断,通过用来向进程通知异步事件。

        本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍,从而更好的理解信号编程。


exit(5)

遵循 C11, POSIX.1 - 2008

1.库

标准 c 库,libc, -lc

2.接口定义

       #include <stdlib.h>

       [[noreturn]] void exit(int status);

3.接口描述

        exit() 函数会导致普通程序终止并将 status 的低字节返回给父进程。

        通过 atexit(3) 和 on_exit(3) 注册的所有函数都会被调到,顺序和注册顺序相反。如果这些函数中有函数没有返回(比如调用了 _exit(2) 或者使用信号杀死了自己),那么剩下的函数都不会调用,剩下的退出过程也会跳过(比如刷新 stdio(3) 流等)。如果一个函数通过上面方式注册了多次,那么每次都会被调用。

        所有打开的 stdio(3) 流都会被刷新并关闭。通过 tmpfile(3) 创建的文件会被删除。

        C 标准规定了两个常量,EXIT_SUCCESS 和 EXIT_FAILURE,可以用来传递给 exit() 指示成功还是失败。        

4.返回值

        exit() 函数不会返回。

5. 属性

        

接口属性
exit()线程安全MT-Unsafe race:exit

        exit() 不是线程安全的,会引起数据竞争问题,关于数据可以参考 attributes(7),在前几篇文章中也有介绍。

 6.注意

        如果通过 atexit(3) 或者 on_exit(3) 注册的函数调用 exit() 或者 longjmp(3),那么产生的行为是未定义的。值得注意的是,调用 execve(2) 会移除通过 atexit(2) 和 on_exit(3) 注册的函数。

        使用 EXIT_SUCCESS 和 EXIT_FAILURE 比用 0 或者非零值(1 或 -1)更具有移植性,尤其是 VMS 会使用不一样的使用习惯。

        BSD 尝试标准化了退出码(GNU C 库已经采用了),可以参考 <sysexits.h>。

        exit() 调用后,退出状态必须传递给父进程。主要有三种情况:

  • 如果父进程设置 SA_NOCLDWAIT 或者设置了 SIGCHLD 的处置函数为 SIG_IGN,那么状态会被忽略,子进程立即死掉
  • 如果父进程正在等待子进程,那么父进程会得到这个退出状态,子进程立即死掉
  • 否则,子进程变成僵尸进程:子进程的大多数资源被回收了,但是系统进程表中的进程槽会保留,来存储一小部分进程信息。这样主要是等待后面父进程通过 waitpid(2)(或者其他函数)来获得子进程的退出信息,那时僵尸进程槽会被释放。

        如果系统实现支持 SIGCHLD 信号,这时会发送这个信号给父进程。如果父进程设置了 SA_NOCLDWAIT,那么是否发送 SIGCHLD 并未定义。

发送给其他进程信号

         如果退出进程是会话 leader 并且其终端正控制着会话,那么每个前台进程组中的进程都会收到 SIGHUP 信号,该终端会从会话上拿掉,允许其他新的控制进程获取该控制权。

         如果退出进程导致一个进程组成为孤儿,并且新产生的孤儿进程组每个进程都停止了,那么会在 SIGCONT 信号后再跟上一个 SIGHUP 信号给进程组中的每个进程。参考 setpgid(2) 来查看关于孤儿进程组的解释。

         除了以上情况,如果要发送的信号是发给要终止进程的子进程的,那么通常情况下是不会向子进程发送信号的。然而进程却可以使用 prctl(2) PR_SET_PDEATHSIG 操作来安全如何处理父进程终止时受到的信号。

8.代码

         下面程序演示了 fork(2) 和 waitpid() 的用法。程序创建了一个子进程,如果没有提供命令行参数,那么子进程会使用 pause(2) 来停止,允许用户向其发送信号。否则如果指定了命令行参数,那么子进程立即返回,使用命令行提供的整数作为返回状态值。父进程循环执行,通过 waitpid() 来监视子进程,使用 W*() 宏来分析返回的状态值。

        下面 shell 会话演示了程序的使用:

           $ ./a.out &
           Child PID is 32360
           [1] 32359
           $ kill -STOP 32360
           stopped by signal 19
           $ kill -CONT 32360
           continued
           $ kill -TERM 32360
           killed by signal 15
           [1]+  Done                    ./a.out
           $

        下面是程序源码: 

       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/wait.h>
       #include <unistd.h>

       int
       main(int argc, char *argv[])
       {
           int    wstatus;
           pid_t  cpid, w;

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {            /* Code executed by child */
               printf("Child PID is %jd\n", (intmax_t) getpid());
               if (argc == 1)
                   pause();                    /* Wait for signals */
               _exit(atoi(argv[1]));

           } else {                    /* Code executed by parent */
               do {
                   w = waitpid(cpid, &wstatus, WUNTRACED | WCONTINUED);
                   if (w == -1) {
                       perror("waitpid");
                       exit(EXIT_FAILURE);
                   }

                   if (WIFEXITED(wstatus)) {
                       printf("exited, status=%d\n", WEXITSTATUS(wstatus));
                   } else if (WIFSIGNALED(wstatus)) {
                       printf("killed by signal %d\n", WTERMSIG(wstatus));
                   } else if (WIFSTOPPED(wstatus)) {
                       printf("stopped by signal %d\n", WSTOPSIG(wstatus));
                   } else if (WIFCONTINUED(wstatus)) {
                       printf("continued\n");
                   }
               } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus));
               exit(EXIT_SUCCESS);
           }
       }

 

 

 


http://www.niftyadmin.cn/n/5059054.html

相关文章

【软件评测】Apowersoft 傲软抠图AI智能换背景工具软件

现如今的数字图像处理已经成为人们生活中不可或缺的一部分&#xff0c;而图像抠图作为其中的重要环节&#xff0c;更是被广泛应用于设计、摄影、广告等领域。为了满足用户的需求&#xff0c;Apowersoft推出了一款傲软抠图AI智能换背景工具&#xff0c;宣称能够自动抠图并智能替…

26617-2011 皖西白鹅 学习笔记

声明 本文是学习GB-T 26617-2011 皖西白鹅. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了皖西白鹅的术语和定义、外貌特征特性、生长性能、繁殖性能、屠宰性能、羽绒性能、种 蛋性状要求。 本标准适用于皖西白鹅品种。 2 规…

网络-跨域解决

文章目录 前言一、跨域是什么&#xff1f;二、跨域的解决1.JSONP2.前端代理dev环境3.后端设置请求头CORS4.运维nginx代理 总结 前言 本文主要介绍跨域问题介绍并提供了四种解决办法。 一、跨域是什么&#xff1f; 准确的来说是浏览器存在跨域问题&#xff0c;浏览器为了安全考…

嵌入式数据库sqlite3子句和函数的使用基础(06)

sqlite在上文中讲解了如何实现sqlite3的基本操作增删改查&#xff0c;本文介绍一些其他复杂一点的操作。比如where、order by、having、like、函数等用法。 数据库准备 新建数据库&#xff0c;company.db。设计一个表格employee&#xff0c;内容如下&#xff1a; idnameaged…

数据探索的新前沿:可视化大屏交互功能

在当今数字化时代&#xff0c;数据和信息是企业成功的关键。可视化大屏已经成为各个行业中数据呈现和决策支持的重要工具。然而&#xff0c;随着技术的发展&#xff0c;用户对于数据可视化的期望也在不断演变。仅仅呈现数据已经不再足够&#xff0c;用户希望能够更深入地与数据…

现场工程师实录: 提高服务器套接字缓存解决大流量 FTP上传丢尾问题

项目场景&#xff1a; FTP是一种非常常用的文件传输工具。在企业中&#xff0c;很多大流量的数据依靠FTP传输。本BUG就是在峰值高流量FTP传输时遇到的问题。 朋友所在公司从事商务管理&#xff0c;有大量的会议过程视频需要归档与留存。各个大区的分公司设置有数据中心&#…

【考研数学】高等数学第七模块 —— 曲线积分与曲面积分 | 1. 对弧长的曲线积分(第一类曲线积分)

文章目录 引言一、曲线积分1.1 对弧长的曲线积分&#xff08;第一类曲线积分&#xff09;1. 问题产生 —— 曲线段的质量2. 对弧长曲线积分的定义3. 对弧长的曲线积分的基本性质4. 对弧长的曲线积分的计算方法 写在最后 引言 终于&#xff0c;这应该是高数的最后一个模块了&am…

【多线程】线程安全的集合类

文章目录 1. 多线程环境使用ArrayList1.1 自己使用同步机制1.2 Collections.synchronizedList(new ArrayList);1.3 使用 CopyOnWriteArrayList 2. 多线程使用队列3. 多线程环境使用哈希表3.1 HashTable3.2 ConcurrentHashMap3.3 Hashtable和HashMap、ConcurrentHashMap 之间的区…