进程同步(三)—— 信号

程序在执行过程经常产生信号,有些是由内核发出,有些是由用户发出。 执行命令kill -l可以查看信号。

这些信号由系统定义,他们不是简单的int之类的数据类型,可能是调用一些函数。 这些信号中,10/12是给用户预留使用的,其他信号各有自己相应的含义。代码中无法完美的自定义信号,容易覆盖或产生系统错误,所以还是乖乖用系统提供的信号吧。 信号类似QT的信号槽的关系,一个信号对应一个处理函数,可以对相应的信号进行屏蔽之类的处理。

信号处理函数属于可重入函数,可以随时中断,允许多个副本执行。 信号处理属于异步处理,和主程是分开执行的,内核发送信号只发送一次。一般处理函数仅仅用于通知主程收到信号,有主程处理具体内容。

下面是信号处理代码,分别是内核发送的子进程结束信号和用户自定义信号。 1 #include <sys/types.h> 2 #include <unistd.h> 3 #include <sys/wait.h> 4 #include <signal.h> 5 #include <string.h> 6 #include <iostream> 7 #include <stdlib.h> 8 9 using namespace std; 10 11 class sigOp 12 { 13 public: 14 void addSigProcess(int sig,void (*func)(int)); 15 void sendSig(const int sig, const int pid); 16 }; 17 void sigOp::addSigProcess(int sig,void (*func)(int)) 18 { 19 struct sigaction stuSig; 20 memset(&stuSig, '\0', sizeof(stuSig)); 21 stuSig.sa_handler = func; 22 stuSig.sa_flags |= SA_RESTART; 23 sigfillset(&stuSig.sa_mask); 24 sigaction(sig, &stuSig, NULL); 25 } 26 void sigOp::sendSig(const int sig, const int pid) 27 { 28 kill(pid, sig); 29 cout<<"send!"<<endl; 30 } 31 void recSig(int sig) 32 { 33 cout<<"rev sig!"<<endl; 34 } 35 void waitchlid(int sig) 36 { 37 pid_t pid; 38 int stat; 39 while((pid = waitpid(-1, &stat, WNOHANG)) > 0); 40 } 41 int main() 42 { 43 sigOp sig; 44 sig.addSigProcess(SIGUSR1, recSig); 45 sig.addSigProcess(SIGCHLD, waitchlid); 46 pid_t pid = fork(); 47 if (pid > 0) 48 { 49 sig.sendSig(SIGUSR1, pid); 50 } 51 else 52 { 53 return 0; 54 } 55 while(1); 56 return 0; 57 }

当我们不处理SIGCHLD信号时,利用ps -aux查看,可以看到进程属于僵尸态。

收到SIGCHLD信号,并且waitpid回收后,没有僵尸进程。 测试结果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏蓝天

Linux进程KILL不掉的原因

做过Linux开发的人通常遇到过一个进程不能kill掉的情况,即使使用的是kill -9方式,而一般的教课书都只说kill -9能杀死任何进程,遇到这种情况时就...

1092
来自专栏Golang语言社区

源目的IP和端口都相同的连接出现的原因

线上遇到了一个比较特殊的连接,它的源目的IP和端口完全相同,复现的场景是:同一个机器上的两个模块A和B通信,A模块会向B模块的监听套接字发起连接请求,B模块重启...

2705
来自专栏Java编程技术

异步打印日志的一点事

最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步...

491
来自专栏行者悟空

Hadoop之RPC机制

731
来自专栏我的博客

TCP/IP三次握手

在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN...

3147
来自专栏Java修行之道

Hibernate中的事务隔离问题(脏读、不可重复读、幻读)

2)一致性:组成事务的各种操作,要么全部成功,要么全部失败。其中有一个失败,事务无法完成

742
来自专栏跟着阿笨一起玩NET

GB2312转换成UTF-8与utf_8转换成GB2312

481
来自专栏运维一切

ceph基础操作记录 原

原因:osd过少或者pool过多,可以清理不用的pool或者增加osd,也可以调节pool的pg数量,这个警告暂时无伤大雅

601
来自专栏Java面试笔试题

JDBC中如何进行事务处理?

Connection提供了事务处理的方法,通过调用setAutoCommit(false)可以设置手动提交事务;当事务完成后用commit()显式提交事务;如果...

592
来自专栏云霄雨霁

网络体系结构

2040

扫码关注云+社区