sigv linux 信号,LINUX 信号处理

转自:http://zhangcy.anytome.com/20060321121911820418131452020050715/35.xml

一 入门

信号是有雷同的或不同的历程向一个历程递交的事件。信号等闲用来向一个历程通知失常事件。

术语:

发生(generate):当导致信号发生的事件揭示时,例如硬件失常,就发生一个针对某个历程的信号

递交(deliver): 当历程对发给它的信号历程处理时,称为改信号被递交。

未决(pending):发生信号和递交信号之间的工夫间隔称为信号未决。

安排(disposition):历程如何响应信号,历程能够疏忽(ignore),厉行默认垄断可能利用自定义代码处理该信号。

linux 按照POSIX.1告终了可靠信号语义 (关于可靠信号与不可靠信号请比照AUPE)。linux

还告终了POSIX.4定义的real-time signals. 号召(kill –l)

能够揭示Linux下所有信号。规范信号和实时信号的差异如下:

规范信号

实时信号

所有信号曾经定义

未定义(前3个已被linuxpthreads-利用)

不能排队(递交前无论发生多少个信号,接受历程只收到一个)。

能够排队 (/proc/sys/kernel/rtsig-max 揭示队列长度)

不能携带其他数据

能够携带其他数据

不能保证时序

保证时序

万一同时有规范信号和实时信号,Linux先处理规范信号

信号处理编程

最容易的信号处理

#include

#include

static void sig_usr(int);

int main()

{

if(signal(SIGUSR1,sig_usr)==SIG_ERR)

perror("cant catch sigusr1");

for(;;)

pause();

return 0;

}

static void sig_usr(int signo)

{

if(signo==SIGUSR1)

printf("recv SIGUSR1/n");

return ;

}

过程运行后,在shell里用号召(kill –USR1 pid )

向过程发送信号,过程就会输出“recv

SIGUSR1”。

这个过程揭示了信号处理的大约过程,率先我们利用signal函数安排了SIGUSR1信号的处理函数,用我们定义的sig_usr轮换了默认函数。然后调用pause使该历程挂起,期待该历程捉拿信号。当历程收到了我们发送的USR1信号是sig_usr就被调用,pause归来,由于是死循环该历程又挂起。

这个过程有一点要解释,signal函数是不评比利用的,因为signal是ANSI

C定义的它对信号的处理的定义极其笼统,全面依靠于垄断系统。有的系统(SVR4)告终的不可靠语义,而BSD告终的是可靠语义。Linux内核和libc4,5和SVR4雷同,而glibc2和BSD雷同,在我的机器上是可靠语义的,鬼才懂得你机器上什么样子。然而因为它容易,因而都拿来入门。

要写过程还是要利用sigset_t相干函数和sigaction,sigprocmask,sigsuspend,sigpendingwww.e4bs.com.

sigset_t 有5个相干函数离别是:

sigemptyset(sigset_t *set); 初始化set指向的信号集,使其打扫所有信号

sigfillset(sigset_t *set); 初始化set指向的信号集,使其包括所有信号。

sigaddset(sigset_t *set ,int signo); 将一个信号增加到现存信号凑近

sigdelset(sigset_t *set,int signo); 从现存信号凑近剔除一个信号

sigismemberset(const sigset_t *set,int signo);

查询一个信号是否在信号凑近。

sigaction 察看或修正与指定信号相干的处理动作。

sigprocmask 察看或修正与指定信号的屏障字

sigsuspend 在一个原子早在中告终还原信号屏障字,然后使历程睡眠。

sigpending 归来对于调用历程被阻塞不能递交和目前未裁决的信号集。

利用sigaction的过程:

#include

#include

static void sig_usr(int);

int main()

{

struct sigaction action;

sigemptyset(&action.sa_mask);

action.sa_handler=sig_usr;

sigaction(SIGUSR1,&action,NULL);

for(;;)

pause();

return 0;

}

static void sig_usr(int signo)

{

if(signo==SIGUSR1)

printf("recv SIGUSR1/n");

return ;

}

sigaction的原型是:

int sigaction(int signum,const struct sigaction *act,struct

sigaction *oldact);

为指定的signum设可信号处理过程,act

是新的信号安排,oldact归来本来的信号安排。sigaction定义如下:

struct sigaction {

void (*sa_handler)(int);

sigset_t sa_mask;

int sa_flags;

void (*sa_restorer)(void);

}

sa_handler是函数指针,指向信号处理函数,也能够是SIG_DEL(设置成默认动作)可能SIG_IGN(疏忽该信号)。sa_mask定义了在指向处理其间该当阻塞的其他信号聚集的掩码。

sa_flags修正sa_handler的行动,能够下面几个值之一:

SA_NOCLDSTOP 历程疏忽子历程发生的任何SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU

SA_ONESHOT 登记的自定义信号处理过程仅厉行顺次。厉行告终后还原默认动作。

SA_RESTART 让可重启的系统调用起作用

SA_NOMASK 不避免在信号自己的处理过程中接受信号本身。

sa_restorer曾经被丢弃。

实时信号编程

// rtsig.c

#include

#include

static void sig_proc(int,siginfo_t *,void *);

int main()

{

struct sigaction action;

sigemptyset(&action.sa_mask);

action.sa_sigaction=sig_proc;

action.sa_flags=SA_SIGINFO;

sigaction(SIGRTMIN+5,&action,NULL);

pause();

return 0;

}

static void sig_proc(int signo,siginfo_t *info,void *p)

{

if(signo==SIGRTMIN+5)

{

int val=info->si_value.sival_int;

// int val=*((int *)info->si_value.sival_ptr);

will be error

printf(da.danbell.com"recv value %d/n",val);

printf("sender pid %d/n",info->si_pid);

printf("signo %d/n",info->si_signo);

}

return ;

}

信号处理过程有两点改变,率先信号处理的接口改变了增加了两个参数,重要的是第二个参数siginfo_t (定义比照man

sigaction),它包括了许多消息,包括发送消息的PID,UID,信号携带的数据。其次sa_flags设成了SA_SIGINFO,只有这么处理过程能力接收到信号携带的数据。

// sendsig.c

#include

#include

int main()

{

int pid,val;

printf("input pid and value :");

scanf("%d %d",&pid,&val);

union sigval sigv;

sigv.sival_int=val; //sigv.sival_ptr=(void

*)&val; will be error

sigqueue(pid,SIGRTMIN+5,sigv);

printf("pid is %d/n",getpid());

return 0;

}

这里发送信号改成了sigqueue, sigval携带信号的数据,比照(man sigqueue)。

过程运行收获:

sendmsg:

input pid and value :24479 232

pid is 24482

rtsig:

recv value 232

sender pid 24482

signo 39起源:

本文就常见的Java代码中轻率揭示的问题提出一些创立性提倡,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值