文档章节

signal信号

小绿豆蛙
 小绿豆蛙
发布于 2014/06/16 15:36
字数 1297
阅读 18
收藏 0
点赞 0
评论 0

1:不可靠信号:信号值小于SIGRTMIN  可以用kill -l 查询,不可靠信号可能会丢了,也就是不支持排队。SIGRTMIN和SIGRTMAX之间的信号支持排队。信号是不是可靠信号与信号安装方式signal或者sigaction无关。

2:信号注册:软中断:给进程表项的信号域设置对应的信号位,如果当前进程可被中断则唤醒,否则仅仅置位。本进程的未决信号:

struct sigpending{

        struct sigqueue *head, *tail; // 未决信号信息链首尾,保存信号携带的信息

        sigset_t signal; //未决信号集

};

struct sigqueue{ //该信号所携带的信息

        struct sigqueue *next;

        siginfo_t info;

};

siginfo_t {
int si_signo; /* 信号值,对所有信号有意义*/
int si_errno; /* errno值,对所有信号有意义*/
int si_code; /* 信号产生的原因,对所有信号有意义*/
union{ /* 联合数据结构,不同成员适应不同信号 */
//确保分配足够大的存储空间
int _pad[SI_PAD_SIZE];
//对SIGKILL有意义的结构
struct{
...
}...

信号在进程中注册就是把信号加入到未决信号集中,他的信息保存到sigqueue节点中,只要信号在未决信号集中就表明进程已经知道该信号了但是还没来得及处理或者被阻塞。

实时信号就是不管这个信号是不是已经注册进去,都会再注册一次所以不会丢失。非实时信号就是如果这个信号已经在队列中(被注册一次了)就不在注册了,所以会造成信号丢失。

3:信号执行和注销

内核处理信号是在该信号产生的上下文中,从内核态返回到用户空间时会检测是否有信号等待处理,如果有则在调用相应信号处理函数之前先把信号从未决信号链中删掉。如果非实时信号,先删除节点再handle,如果是实时信号,则全部handles处理完再集中删除。

当所有未决信号都处理完即可返回用户态,对于被屏蔽的信号,如果取消屏蔽则返回用户态时会再次检测同上。

如果进程受到一个要捕捉的信号,在进程从内核态转换到用户态时执行用户定义函数【内核在用户栈上创建一个新的层,该层将返回的地址设置成用户定义的handles函数地址,handle函数返回之后弹出栈顶时,返回原来进入内核地方:目的用户自定义处理函数不能在内核态下运行】。

对于32位系统(每个字32位),信号最多有32种,对于64位系统(每个字64位)信号最多有64种(/include/asm/signal.h)。内核中中断的响应和处理都是在内核态,信号的响应在内核态,处理在用户态。内核中不存在信号优先级,的那个多个信号发出时进程以任意顺序处理信号。

4:信号安装:

signal(signum, signal_handle_fun)

int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));

s第二、三参数为NULL时候可检测信号。igaction结构定义如下:

struct sigaction {

                       union{

                               __sighandler_t _sa_handler; //

                               void (*_sa_sigaction)(int,struct siginfo *, void *); //信号处理函数,siginfo携带了信号的详细信息的结构体

                       }_u

            sigset_t sa_mask; //信号屏蔽字

            unsigned long sa_flags; //信号标志位

}

5信号发送:kill(pid_t pid, signo)  pid = 0:同一个进程组进程、= -1:除进程以外所有>1的进程、signo=0检测进程是否存在是否有发送权限等等。【非root只能向同一个用户发送信号:errno=EINVAL:信号无效,ESRCH:进程无效,EPERM:进程无权限发信号】

sigqueue(pid_t pid, int sig, const union sigval val)与sigaction配合使用。

setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)函数:

struct itimerval {

        struct timeval it_interval; /* 下一次的取值:下次计时值,如果是0下次停止*/

        struct timeval it_value; /* 本次的设定值:本次计时结束发送一个ALRM信号,之后该变量被设置为it_interval值*/

}; 

该结构中timeval结构定义如下:

struct timeval {

        long tv_sec; /* 秒 */

        long tv_usec; /* 微秒,1秒 = 1000000 微秒*/

};

eg:>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    signal(SIGVTALRM, sigroutine); 

        value.it_value.tv_sec = 1;

        value.it_value.tv_usec = 0;

        value.it_interval.tv_sec = 1;

        value.it_interval.tv_usec = 0;

        setitimer(ITIMER_REAL, &value, &ovalue);

eg:>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

信号集及其操作函数:

typedef struct {

                       unsigned long sig[_NSIG_WORDS];

} sigset_t

信号集屏蔽的作用:就是将不用的信号暂时遮掩起来等用的时候或者恢复环境时候在拿去遮掩。

实例:不同进程之间传递信号:

信号接收程序:

#include <signal.h>

#include <sys/types.h>

#include <unistd.h>

void new_op(int,siginfo_t*,void*);

int main(int argc,char**argv)

{        struct sigaction act;

        int sig;

        pid_t pid;              

        pid=getpid();

        sig=atoi(argv[1]);            

        sigemptyset(&act.sa_mask);

        act.sa_sigaction=new_op;

        act.sa_flags=SA_SIGINFO;

        if(sigaction(sig,&act,NULL)<0)

        {

                printf("install sigal error\n");

        }

        while(1)

        {

                sleep(2);

                printf("wait for the signal\n");

        }

}

void new_op(int signum,siginfo_t *info,void *myact)

{

        printf("the int value is %d \n",info->si_int);

}

信号发送程序:

#include <signal.h>

#include <sys/time.h>

#include <unistd.h>

#include <sys/types.h>

main(int argc,char**argv)

{

        pid_t pid;

        int signum;

        union sigval mysigval;

        signum=atoi(argv[1]);

        pid=(pid_t)atoi(argv[2]);

        mysigval.sival_int=8;//不代表具体含义,只用于说明问题

        if(sigqueue(pid,signum,mysigval)==-1)

                printf("send error\n");

        sleep(2);

}

© 著作权归作者所有

共有 人打赏支持
小绿豆蛙
粉丝 0
博文 30
码字总数 13280
作品 0
海淀
程序员
Linux 信号signal处理函数

alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include 定义函数 unsigned int alarm(unsigned int seconds); 函数说明 alarm()用来设置信号SIGALRM在经过参数seconds指定的秒...

长平狐 ⋅ 2013/01/06 ⋅ 0

Linux 信号signal处理函数

alarm(设置信号传送闹钟) 相关函数 signal,sleep 表头文件 #include 定义函数 unsigned int alarm(unsigned int seconds); 函数说明 alarm()用来设置信号SIGALRM在经过参数seconds指定的秒...

晨曦之光 ⋅ 2012/03/02 ⋅ 0

python blinker 库学习

创建信号 信号通过signal()方法进行创建: >>> from blinker import signal >>> initialized = signal("initialized") >>> initialized is signal("initialized") True 每次调用signal('nam......

铁扇公主1 ⋅ 2017/04/07 ⋅ 0

linux c简单了解signal

一、什么是信号 1、 信号就是软件中断,很多的程序都需要处理信号。信号提供了一种处理异步事件的机制。 例如:当用户在终端下运行一个程序时,用户在键盘键入一个中断键(CTRL+C),则会通过信...

OscerSong ⋅ 2013/03/10 ⋅ 1

linux内核中的信号机制--信号发送

linux内核中的信号机制--信号发送 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net/ce123) 应用程序发送信号时,主要通过kill进行。注意:不要被“k...

长平狐 ⋅ 2013/06/03 ⋅ 0

linux C多线程下信号的使用

在Linux的多线程中使用信号机制,与在进程中使用信号机制有着根本的区别,可以说是完全不同。在进程环境中,对信号的处理是,先注册信号处理函数,当信号异步发生时,调用处理函数来处理信号...

So_care_about_y ⋅ 2017/08/18 ⋅ 0

[iOS开发]使用signal让app能够在从容崩溃

前言 虽然大家都不愿意看到程序崩溃,但可能崩溃是每个应用必须面对的现实,既然崩溃已经发生,无法阻挡了,那我们就让它崩也崩得淡定点吧。 iOS SDK中提供了一个现成的函数 NSSetUncaughtE...

浩浩老师 ⋅ 2015/09/07 ⋅ 0

Linux捕捉信号机制之(signal,kill)、(sigaction,sigqueue)

linux下公有64个信号,kill -l 查看一下:可以看到,缺少了32、33两个未知信号,从这里分界,前面31个信号是不可靠信号,后面的是可靠信号。当进程发生阻塞的时候(一下子发送很多信号),不...

SherryX ⋅ 2017/12/15 ⋅ 0

nginx源码分析—信号初始化

作者:阿波 链接:http://blog.csdn.net/livelylittlefish/article/details/7308100 Content 0.序 1. ngxinitsignals()函数 1.1 ngxsignalt结构 1.2 signals数组 1.3 sigaction结构 2.几个问......

晨曦之光 ⋅ 2012/03/09 ⋅ 0

linux中的信号2——进程如何处理信号?

以下内容源于朱有鹏《物联网大讲堂》课程的学习整理,如有侵权,请告知删除。 1、signal函数介绍 (1)举例:用signal函数处理SIGINT信号(这个信号由ctrl+c时发出) 默认处理 忽略处理 捕获...

oqqhutu12345678 ⋅ 2017/07/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部