linux内核中的信号机制--从用户层到内核层
时间:11-22
来源:互联网
点击:
Kernel version:2.6.14
CPU architecture:ARM920T
Author:ce123(http://blog.csdn.net/ce123)
1.简介
如果进程要处理某一信号,那么要在进程中注册该信号。注册信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个进程和该信号被传递给进程时,将执行何种操作。主要有两个函数实现信号的注册:signal()和sigaction()。
2.signal()
signal()的函数原型如下:
[plain]view plaincopyprint?
- void(*signal(intsignum,void(*handler)(int)))(int);
[plain]view plaincopyprint?
- #include
上述声明格式比较复杂,如果不清楚如何使用,也可以通过下面这种类型定义的格式来使用(POSIX的定义):
[plain]view plaincopyprint?
- typedefvoid(*sighandler_t)(int);
- sighandler_tsignal(intsignum,sighandler_thandler);
- SIG_IGN:忽略参数signum所指的信号。
- SIG_DFL:恢复参数signum所指信号的处理方法为默认值。
signal()通过系统调用sys_signal()为一个指定的信号设置用户态处理函数。sys_signal()定义如下:
[plain]view plaincopyprint?
- /*
- *Forbackwardscompatibility.Functionalitysupersededbysigaction.
- */
- asmlinkageunsignedlong
- sys_signal(intsig,__sighandler_thandler)
- {
- structk_sigactionnew_sa,old_sa;
- intret;
- new_sa.sa.sa_handler=handler;
- new_sa.sa.sa_flags=SA_ONESHOT|SA_NOMASK;
- ret=do_sigaction(sig,&new_sa,&old_sa);
- returnret?ret:(unsignedlong)old_sa.sa.sa_handler;
- }
__sighandler_t的定义如下:
[plain]view plaincopyprint?
- typedefvoid__signalfn_t(int);
- typedef__signalfn_t__user*__sighandler_t;
信号由sys_signal()的第一个参数指定,信号处理函数的地址由第二个参数指定。sys_signal()根据这两个参数设置一个k_sigaction结构,然后调用do_sigaction(),该函数的定义我们会在后面具体讲解。
2.sigaction()
sigaction()的函数原型如下:
[plain]view plaincopyprint?
- sigaction(intsignum,conststructsigaction*act,structsigaction*oldact);
2.1do_sigaction()
[plain]view plaincopyprint?
- int
- do_sigaction(intsig,conststructk_sigaction*act,structk_sigaction*oact)
- {
- structk_sigaction*k;
- if(!valid_signal(sig)||sig<1||(act&&sig_kernel_only(sig)))
- return-EINVAL;
- k=¤tt->sighand->action[sig-1];
- spin_lock_irq(¤tt->sighand->siglock);
- if(signal_pending(current)){
- /*
- *Iftheremightbeafatalsignalpendingonmultiple
- *threads,makesurewetakeitbeforechangingtheaction.
- */
- spin_unlock_irq(¤tt->sighand->siglock);
- return-ERESTARTNOINTR;
- }
- if(oact)//把原来的k_sigaction保存到oact结构中,这里是对整个数据结构进行复制
- *oact=*k;
- if(act){
- /*
- *POSIX3.3.1.3:
- *"SettingasignalactiontoSIG_IGNforasignalthatis
- *pendingshallcausethependingsignaltobediscarded,
- *whetherornotitisblocked."
- *
- *"SettingasignalactiontoSIG_DFLforasignalthatis
- *pendingandwhosedefaultactionistoignorethesignal
- *(forexample,SIGCHLD),shallcausethependingsignalto
- *bediscarded,whetherornotitisblocked"
- */
- if(act->sa.sa_handler==SIG_IGN||
- (act->sa.sa_handler==SIG_DFL&&
- sig_kernel_ignore(sig))){
- /*
- *Thisisafairlyrarecase,soweonlytakethe
- *tasklist_lockonceweresurewellneedit.
- *Nowwemustdothislittleunlockandrelock
- *dancetomaintainthelockhierarchy.
- */
- structtask_struct*t=current;
- spin_unlock_irq(&t->sighand->siglock);
- read_lock(&tasklist_lock);
- spin_lock_irq(&t->sighand->siglock);
- *k=*act;//把新的k_sigaction结构复制到进程的sighand->action中
- sigdelsetmask(&k->sa.sa_mask,
- sigmask(SIGKILL)|sigmask(SIGSTOP));
- rm_from_queue(sigmask(sig),&t->signal->shared_pending);
- do{
- rm_from_queue(sigmask(sig),&t->pending);
- recalc_sigpending_tsk(t);
- t=next_thre
linux内核信号机制-用户层内核 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)