信号处理

⟅UNIX网络编程⟆⦔wait和waitpid函数-补充

扶醉桌前 提交于 2020-01-25 17:37:51
目录 说在前面 问题提出 问题解决 说在前面 环境: WSL、ubuntu16 参考: UNIX网络编程、 linux manual page 目录: 这里 本体: ⟅UNIX网络编程⟆⦔wait和waitpid函数 问题提出 见 问题 已知while(waitpid)是回收所有已终止进程的,但是它是如何解决“ 信号处理函数不可重入 ”的问题? 疑问来源: 在信号处理函数sig_child中如果使用wait,是不可以保证回收所有已终止的子进程。 在书上说是因为,“所有信号都在信号处理函数执行之前产生,而信号处理函数只执行一次”(因为在sig_child函数调用期间,SIGCHLD信号是阻塞的) 使用waitpid可以解决上述问题,因为WNOHANG可以让waitpid立即返回。 但是WNOHANG应该没有解决“所有信号都在信号处理函数执行之前产生,而信号处理函数只执行一次”(即信号处理函数不可重入)这个问题。 问题解决 首先, wait和waitpid,都不是用SIGCHLD触发的,只是很多人喜欢在信号处理函数里用wait/waitpid ; 其次, 在信号处理函数中用wait.waitpid是有风险的,信号处理函数时不能重入的,即如果信号函数没执行完,再来一个信号,有可能导致进程死锁 ; 推荐的用法, 信号处理函数中置标记位,退出信号处理函数后根据标记位调用wait

信号处理——EMD、VMD的一点小思考

我是研究僧i 提交于 2020-01-22 23:49:33
作者:桂。 时间:2017-03-06 20:57:22 链接: http://www.cnblogs.com/xingshansi/p/6511916.html 前言 本文为 Hilbert变换一篇 的内容补充,主要内容为:   1)EMD原理介绍   2)代码分析   3)一种权衡的小trick   4)问题补充 内容主要为自己的学习总结,并多有借鉴他人,最后一并给出链接。 一、EMD原理介绍   A-EMD的意义 很多人都知道EMD(Empirical Mode Decomposition)可以将信号分解不同频率特性,并且结合Hilbert求解包络以及瞬时频率。 EMD、Hilbert、瞬时频率三者有无内在联系?答案是:有。 按照 Hilbert变换一篇 的介绍, $f(t) = \frac{{d\Phi (t)}}{{d(t)}}$ 然而,这样求解瞬时频率在某些情况下有问题,可能出现$f(t)$为负的情况:我1秒手指动5下,频率是5Hz;反过来,频率为8Hz时,手指1秒动8下,可如果频率为-5Hz呢?负频率没有意义。 考虑信号 $x(t) = {x_1}(t) + {x_2}(t) = {A_1}{e^{j{\omega _1}t}} + {A_2}{e^{j{\omega _2}t}} = A(t){e^{j\varphi (t)}}$ 为了简单起见,假设$A_1$和$A

Linux信号机制(二)-- 信号集

扶醉桌前 提交于 2020-01-17 15:24:18
什么是信号集? 收到一个信号之后执行信号处理函数,在执行信号处理函数的过程中如果又来了一个相同的信号,那么这个信号将会被阻塞,直到信号处理函数执行完之后,再响应被阻塞的信号,注意如果信号被阻塞期间又收到了该信号,那么多个信号的处理会被合并为1次 比如正在执行SIGUSR1的信号处理函数,此时又收到了一个SIGUSR1信号,那么该信号将会被阻塞,直到信号处理函数执行完之后,再次执行该函数。如果在阻塞期间又收到了SIGUSER1信号,接下来只再调用一次SIGUSR1的信号处理函数 信号集就是用来记录当前收到了哪个信号,会把当前信号的标志位置成“正在处理”,如果此时再收到该信号,那么信号就阻塞等待 使用数据类型sigset_t表示信号集,在Linux中该类型是一个32位无符号整数,这是因为在Linux中定义了32种信号,每一个信号用32位无符号整型变量中的一位来标志,如果该位置为1,那么表示正在处理该信号,如果置为0表示可以处理该信号。注意:有的操作系统,信号个数多于32,此时就不能用32位整数表示一个信号集了 操作信号集的函数 函数原型如下: [1] #include <signal.h> // @brief 清空信号集,全部位置0 int sigemptyset(sigset_t *set); // 全部位置1 int sigfillset(sigset_t *set); //

c sigaction信号处理

强颜欢笑 提交于 2020-01-01 00:27:53
头文件:#include <signal.h> 原型: int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 参数: signum是除了SIGKILL和SIGSTOP之外的任何信号; act非空,新的动作(信号到来时执行的函数)存在act中,如果旧的动作非空,旧动作存在oldact中; 返回值: sigaction() returns 0 on success and -1 on error. sigaction结构体如下: struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; sa_restorer已经废弃不用了; sa_handler就是执行的动作,指向函数的指针,函数接收signum作为其参数,也可以是SIG_DFL默认动作或者SIG_IGN忽略该信号; 。。。 signum可以有哪些,分别什么意思? 在signum.h中, /* Signals. */ #define SIGHUP 1 /* Hangup

信号处理

非 Y 不嫁゛ 提交于 2020-01-01 00:26:10
1 linux系统中对信号的处理主要由signal和sigaction函数来完成 Signal函数用来设置进程在接收到信号时的动作 #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum,sighandler_t handler); signal会根据参数signum指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。如果参数handler不是函数指针,最必须是常数SIG_IGN(忽略该信号)或者SIG_DFL(对该信号执行默认操作)。 signal函数执行成功时返回以前的信号处理函数指针,当有错误发生时返回SIG_ERR(-1) int sigaction(int signum,const struct sigaction *act, struct sigaction *oldact); 2 信号处理函数的返回 setjmp/longjmp 使用longjmp可以跳转到setjmp设置的位置 #include <setjmp.h> int setjmp(jmp_buf env); void longjmp(jmp_buf env,int val); sigsetjmp/siglongjmp 和setjmp

Linux&C ——信号以及信号处理

狂风中的少年 提交于 2020-01-01 00:25:51
linux信号的简单介绍 信号的捕捉和处理 信号处理函数的返回 信号的发送 信号的屏蔽 一:linux信号的简单介绍。 信号提供给我们一种异步处理事件的方法,由于进程之间彼此的地址空间是独立的,所以进程之间的通信就需要特殊的机制,而信号是进程之间唯一的异步通信方式。我们平时可以接触到的信号来源一般有:用户从键盘键入、一些硬件的异常、用户使用kill命令或者函数发送或者当系统检测到某种软件已经具有发出信号的条件(比如alarm或settimer设置的定时器超时时将生成SIGALRAM信号),linux下的信号种类有60多种,我们可以输入下面的命令查看: $ kill -l 其中1~31为不可靠信号(可能会丢失,信号不支持排队),33~64为可靠信号,也叫做实时信号。在linux中,当导致信号的事件发生时,内核就会产生一个信号,信号产生后,内核通常会在进程表中设置某种形式的标志,即内核向一个进程递送了一个信号,信号产生和递送之间的时间间隔叫做“信号未决”。我们用户在产生信号之后可以要求进程对信号做出以下处理,例如捕捉信号,处理信号,忽略信号等。 二:信号的捕捉和处理。 1:signal()函数 typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 这个定义等价于

Linux 进程间通信系列之 信号

雨燕双飞 提交于 2020-01-01 00:22:04
信号(Signal) 信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;Linux除了支持Unix早期信号 语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又 能够统一对外接口,用sigaction函数重新实现了signal函数) 信号种类 每种信号类型都有对应的信号处理程序(也叫信号的操作),就好像每个中断都有一个中断服务例程一样。大多数信号的默认操作是结束接收信号的进程;然而,一个进程通常可以请求系统采取某些代替的操作,各种代替操作是: 忽略信号。随着这一选项的设置,进程将忽略信号的出现。有两个信号 不可以被忽略:SIGKILL,它将结束进程;SIGSTOP,它是作业控制机制的一部分,将挂起作业的执行。 恢复信号的默认操作。 执行一个预先安排的信号处理函数。进程可以登记特殊的信号处理函数。当进程收到信号时,信号处理函数将像中断服务例程一样被调用,当从该信号处理函数返回时,控制被返回给主程序,并且继续正常执行。 但是,信号和中断有所不同。中断的响应和处理都发生在内核空间,而信号的响应发生在内核空间,信号处理程序的执行却发生在用户空间。 那么,什么时候检测和响应信号呢?通常发生在两种情况下: 当前进程由于系统调用

信号中断与异步信号中断安全编程

故事扮演 提交于 2020-01-01 00:21:50
1、什么是中断? 1.1、什么是中断 外围设备的速度远低于CPU的速度,所以为提高CPU计算效率,现代计算机变内核主动为硬件主动,只在硬件需要的时候才发送信号,通知内核来处理数据。这样外围设备与内核的协作方式即为中断机制。而设备发送的信号即为中断,其本质为一种特殊的电信号。 硬中断处理流程: 1、各外围设备与中断管理器各输入引脚相连; 2、中断管理器与CPU之间只存在一条中断管线; 3、设备发送一个中断到中断管理器; 4、中断管理器发送对应电信号给CPU。 5、CPU中断当前工作,开始处理中断,并通知操作系统。 6、操作系统调用中断处理程序。 中断的特点: 1、不同的设备对应不同的中断,并被用数字标识; 2、对应的设备需要对应的中断处理程序; 3、中断值即中断请求线(IRQ),被关联到不同的数值量,如IRQ 0,中断亦可动态分配。 4、设备中断信号可能在任意时刻到来,不与CPU时钟同步,即异步硬件中断。 糕富帅CPU来到女儿国,女儿国的妹子们(中断集合)精心打扮,总在认为打扮完美的时刻向糕富帅抛媚眼露大腿扮性感,引起糕富帅的注意。糕富帅玩弄妹子的手段高超,经验丰富,与最靓的妹纸牵手,喜欢为不同的妹子编号并制定不同的攻略策略,总是上半场激烈,下半场缠绵,中场偷腥不断,并在腻味之后回归原始的浪荡生活。妹纸们总是很傻很天真,屡败屡战,不停地打扮自己,完美自己,期待着与糕富帅的重新开始。

信号

断了今生、忘了曾经 提交于 2019-12-30 13:54:57
文章目录 一、信号及其处理过程 1、概述 1.1、发送信号 1.2、待处理信号集合 1.3、接收信号与阻塞信号 1.4 信号处理函数的终止 2、发送信号 2.1、kill函数 2.1.1、其中pid的值: 2.1.2、信号发送的权限: 2.1.3、错误返回的errno标志 2.1.4、Linux权限管理(拓展) 2.2、发送信号的其他方式 2.2.1、raise函数(向自身发送信号) 2.2.2、killpg函数 3、信号集、待处理信号、阻塞信号 3.1、信号集处理: 3.2、处于等待状态的信号 3.3、阻塞信号传递(信号掩码) 3.3.1、概述 3.3.2、sigprocmask函数 4、改变信号处理 4.1、信号的默认行为 4.2、signal()函数 4.2.1、可移植性说明 4.3、sigaction()函数 4.3.1、与signal函数的比较 4.3.2、sa_flag信号说明 4.3.2.1、signal函数实现——使用sa_flag的实例 4.3.2.2、abort函数实现——使用sa_flag的实例 4.3.2.2.1、abort函数的功能 4.3.2.2.2、abort函数的实现 4.3.2.3、sigaltstack函数——实现SA_ONSTACK的基础 5、常用信号及其说明 5.1 SIGKILL(终止进程)和SIGSTOP(停止进程) 5.1.1

linux下的C语言开发(七):信号处理

回眸只為那壹抹淺笑 提交于 2019-12-27 07:28:45
信号处理是linux程序的一个特色。用信号处理来模拟操作系统的中断功能,对于我们这些系统程序员来说是最好的一个选择了。要想使用信号处理功能,你要做的就是填写一个信号处理函数即可。一旦进程有待处理的信号处理,那么进程就会立即进行处理。 #include <stdio.h> #include <stdlib.h> #include <signal.h> int value = 0; void func(int sig) { printf("I get a signal!\n"); value = 1; } int main() { signal(SIGINT, func); while(0 == value) sleep(1); return 0; } 为了显示linux对signal的处理流程,我们需要进行两个步骤。第一,输入gcc sig.c -o sig, 然后输入./sig即可;第二则重启一个console窗口,输入ps -aux | grep sig, 在获取sig的pid之后然后输入kill -INT 2082, 我们即可得到如下的输出。 ———————————————— 版权声明:本文为CSDN博主「费晓行」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/feixiaoxing