Linux网络编程笔记6 信号_原进程被忽略的信号 新进程

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

              /  \
             /事件 \

过程(进程)2 /—v—
/
/
过程(进程)3 /— —\


信号是提供异步事件处理机制的软件中断。这些异步事件可能来自硬件设备,也可能来自系统内核,甚至可能来自用户程序。进程之间可以相互发送信号,这使信号成为一种进程间通信(Inter-Process Communication, IPC)的基本手段。信号的异步特性不仅表现为它的产生是异步的,对它的处理同样也是异步的。程序设计者不可能也不需要精确地预见什么时候触发什么信号,也同样无法预见该信号究竟在什么时候会被处理。一切尽在内核操控下异步地发生。


2)什么是信号处理?  
 每一个信号都有其生命周期:  
 产生:信号被生成,并被发送至系统内核  
 未决:信号被内核缓存,而后被递送至目标进程  
 递送:内核已将信号发送至目标进程  
 忽略 - 什么也不做。  
 捕获 - 暂定当前的执行过程,转而调用一个事先写好的信号处理函数,待该函数完成并返回后,再继续之前被中断的过程。  
 默认 - 既不忽略该信号,也不用自己定义处理方式,而是按照系统默认的方式予以响应。  
 激励(信号)->响应(信号处理)


3)信号的名称和编号  
 信号名称:形如SIGXXX的字符串或宏定义,提高可读性。  
 信号编号:整数  
 通过kill -l命令查看当前系统所支持的全部信号名称及其编号。  
 1~31,31个不可靠信号,也叫非实时信号。  
 34~64, 31个可靠信号,也叫实时信号。  
 共62个信号,注意没有32和33信号。  
 SIGHUP(1),控制终端关闭,终止  
 SIGINT(2),用户产生中断符(Ctrl+C),终止  
 SIGQUIT(3),用户产生退出符(Ctrl+),终止+转储  
 SIGBUS(7),硬件或内存对齐错误,终止+转储  
 SIGKILL(9),不能被捕获和忽略,终止  
 SIGSEGV(11),无效内存访问,终止+转储  
 SIGPIPE(13),向读端已关闭的管道写入,终止  
 SIGALRM(14),alarm函数设置的闹钟到期,终止  
 SIGTERM(15),可被捕获和忽略,终止  
 SIGCHLD(17),子进程终止,忽略  
 SIGIO(29),异步I/O事件,终止  
 举例:写一个死循环



#include <stdio.h>
#include <unistd.h>
int main(void) {

printf("PID: %d\n", getpid());
for (;;);
return 0;

}


kill -SIGQUIT 进程pid 进程pid …  
 kill -SIGQUIT -1 给所有进程发QUIT信号


### 2.捕获信号


#include <signal.h>  
 typedef void (\*sighandler\_t) (int);  
 |  
 函数指针  
 指向一个接受整型参数且无返回值的函数  
 设置针对特定信号的处理方式,即捕获特定的信号:  
 sighandler\_t signal(int signum, sighandler\_t handler);  
 成功返回原信号处理方式,失败返回SIG\_ERR(sighandler\_t类型的-1)。  
 signum - 信号编号  
 handler - 信号处理函数指针,也可以取以下值:  
 SIG\_IGN - 忽略信号  
 SIG\_DFL - 默认操作  
 …  
 // 定义信号处理函数  
 void sigint (int signum) {
   
 SIGINT(2)信号的处理代码  
 }  
 …  
 // 捕获SIGINT(2)信号  
 if (signal(SIGINT, sigint) == SIG\_ERR) {
   
 perror(“signal”);  
 return -1;  
 }  
 …



                    SIGINT(2)
                      v

SIGINT(2)/PID/sigint->系统内核
v
目标进程中的sigint函数


signal(SIGINT, SIG\_DFL); // 按默认方式处理  
 signal(SIGINT, SIG\_IGN); // 忽略信号  
 当一个信号正在被处理的过程中,相同的信号再次产生,该信号会被阻塞,直到前一个信号处理完成,即从信号处理函数中返回,后一个被阻塞的信号才被递送,进而再次执行信号处理函数。当一个不可靠信号正在被处理的过程中,多个相同的信号再次产生,只有第一个信号会被阻塞,其它信号直接丢弃,如果是可靠信号,都会被阻塞,并按照产生的顺序依次被递送。  
 信号处理函数及被其调用的函数都有可能发生重入,由此可能引发无可预知的风险。  
 global = 0;  
 …  
 ++global;  
 …  
 所有标准I/O函数都是不可重入函数。在信号处理的过程中要慎用。



A信号->A信号处理函数 \ 打印AAAAAA
> printf(调试信息);
B信号->B信号处理函数 / 打印BBBBBB
AAABBBBBBAAA


代码:signal.c



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void sigint(int signum) {

signal(SIGINT, SIG_DFL);//一次性问题
printf("%d进程:收到%d信号!\n",
    getpid(), signum);
signal(SIGINT, sigint);//不让系统出现一次性问题

}
void sigterm(int signum) {

printf("%d进程:收到%d信号!\n",
    getpid(), signum);
printf("妥当善后...\n");
exit(0);

}
int main(void) {

if (signal(/\*2\*/SIGINT, sigint) == SIG_ERR) {

    perror("signal");
    return -1;
}
if (signal(/\*3\*/SIGQUIT, SIG_IGN) ==
    SIG_ERR) {

    perror("signal");
    return -1;
}
if (signal(/\*9\*//\*SIGKILL\*//\*15\*/SIGTERM,
    /\*SIG\_IGN\*/sigterm/\*SIG\_DFL\*/)==SIG_ERR){

//9信号不能被忽略,也不能捕获
perror(“signal”);
return -1;
}
for (;😉;
return 0;
}


### 3.信号捕获流程



                  中断

主控制流程--------- v ----------->
/
信号处理函数 / ------> \ 用户空间
/ \ / \ ---------
/ \ / \ 内核空间
内核处理流程-----------> ---------->
do_signal system_call
V V
handle_signal sys_sigreturn
V V
setup_frame restore_sigcontext


信号的本质是一个中断的处理过程,而非多线程的并发过程。



线程安全的函数未必是可重入函数。
V V
锁机制 局部化


### 4.信号捕获的一次性问题


在某些非Linux操作系统上,存在信号捕获的一次性问题:  
 即使设置了对某个信号的捕获,只有设置后的第一个该信号被递送时,信号处理函数会被执行,以后再来相同的信号,均按默认方式处理。如果希望对信号的捕获具有持久性,可以在信号处理函数返回前再次设置对该信号的捕获。


### 5.太平间信号


通过SIGCHLD(17)信号高效地回收子进程僵尸。  
 高效:及时性,适时性。  
 代码:sigchld.c



#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
void sigchld(int signum) {

for (;;) {

//为了收集所有僵尸,故循环
pid_t pid = waitpid(-1, NULL, WNOHANG);//非阻塞
if (pid == -1) {

        if (errno != ECHILD) {

            perror("wait");
            exit(-1);
        }
        printf("父进程:所有子进程"
            "都已终止。\n");
        break;
    }
    if (!pid) {

        printf("父进程:暂时没有可回收的"
            "子进程。\n");
        break;
    }
    printf("父进程:%d子进程终止。\n", pid);
}
usleep(100000);//为了观察现象

}
int main(void) {

if (signal(SIGCHLD, sigchld) == SIG_ERR) {

    perror("signal");
    return -1;
}
for (int i = 0; i < 5; ++i) {

    pid_t pid = fork();
    if (pid == -1) {

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值