文档章节

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);

}

© 著作权归作者所有

共有 人打赏支持
小绿豆蛙
粉丝 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 信号signal处理函数

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

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

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

晨曦之光
2012/03/02
158
0
linux内核中的信号机制--信号发送

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

长平狐
2013/06/03
363
0
linux C多线程下信号的使用

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

So_care_about_y
2017/08/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx的简单使用:负载均衡

nginx:反向代理的服务器;用户发送请求到nginx,nginx把请求发送给真正的服务器,等待服务器处理完数据并返回,再把数据发送给用户。 nginx作为一个反向代理服务器,能缓存我们项目的静态文...

osliang
16分钟前
1
0
网站title标题被改并被百度网址安全中心提醒的解决办法

国庆假日期间我们Sine安全接到众多网站站长求助网站标题被改导致在百度搜索中百度安全中心提醒被拦截,导致网站正常用户无法浏览网站被跳转到一些菠菜du博网站,而且很明显的一个特征就是在百...

网站安全
18分钟前
1
0
JDK版本与major.minor version的对照关系

其实,只需要记住jdk6对于major.minor version 50即可,其他版本自行计算即可。 ---------------------

码代码的小司机
20分钟前
1
0
C++基础教程面向对象学习笔记及心得感悟[图]

C++基础教程面向对象学习笔记及心得感悟[图] 使用友元函数重载算术运算符: C ++中一些最常用的运算符是算术运算符 - 即加号运算符(+),减运算符( - ),乘法运算符(*)和除法运算符(/...

原创小博客
29分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部