文档章节

signal信号

小绿豆蛙
 小绿豆蛙
发布于 2014/06/16 15:36
字数 1297
阅读 18
收藏 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);

}

© 著作权归作者所有

共有 人打赏支持
上一篇: void类型
小绿豆蛙
粉丝 0
博文 33
码字总数 13280
作品 0
海淀
程序员
私信 提问
python blinker 库学习

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

铁扇公主1
2017/04/07
52
0
linux C多线程下信号的使用

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

So_care_about_y
2017/08/18
0
0
linux c简单了解signal

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

OscerSong
2013/03/10
0
1
Linux 信号signal处理函数

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

长平狐
2013/01/06
93
0
Linux 信号signal处理函数

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

晨曦之光
2012/03/02
169
0

没有更多内容

加载失败,请刷新页面

加载更多

Caffe(二)-Python-自定义网络

这里我们用一个例子先来体验一下 首先定义一下我们的环境变量 $PYTHONPATH,我这儿是Windows开发环境,至于Windows Caffe怎么编译由读者自己下去搞定 我使用的控制台是 Windows PowerShell 添...

Pulsar-V
39分钟前
3
0
ActiveMQ从入门到精通(二)之可靠性机制

ActiveMQ的可靠性机制 缘由( 确认JMS消息) 只要消息被确认之后,才认为消息被成功消费了。消息的成功消费包括三个阶段:客户端接收消息、客户端处理消息以及客户端确认消息。在事务性会话中...

一看就喷亏的小猿
46分钟前
1
0
源码分析 Mybatis 的 foreach 为什么会出现性能问题

背景 最近在做一个类似于综合报表之类的东西,需要查询所有的记录(数据库记录有限制),大概有1W条记录,该报表需要三个表的数据,也就是根据这 1W 个 ID 去执行查询三次数据库,其中,有一...

TSMYK
今天
7
0
IC-CAD Methodology企业实战之openlava

在云计算解决安全问题并成为IC界主流运算平台之前,私有的服务器集群系统仍然是各大IC公司的计算资源平台首选。 现在主流的服务器集群管理系统包括lsf,openlava,SkyForm,三者都属于lsf一系...

李艳青1987
今天
7
0
http response stream 字节流 接收与解码

在接收图片、音频、视频的时候,需要用到二进制流。 浏览器会发给客户端 字节Byte流,一串串的发过来_int8格式 -128~127(十进制),也就是8bit(位)。 客户端接收的时候,对接收到的字节收集,...

大灰狼wow
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部