linux内核层是什么,从用户层到内核层 - Linux内核中的信号机制_Linux编程_Linux公社-Linux系统门户网站...
1.簡(jiǎn)介
如果進(jìn)程要處理某一信號(hào),那么要在進(jìn)程中注冊(cè)該信號(hào)。注冊(cè)信號(hào)主要用來(lái)確定信號(hào)值及進(jìn)程針對(duì)該信號(hào)值的動(dòng)作之間的映射關(guān)系,即進(jìn)程將要處理哪個(gè)進(jìn)程和該信號(hào)被傳遞給進(jìn)程時(shí),將執(zhí)行何種操作。主要有兩個(gè)函數(shù)實(shí)現(xiàn)信號(hào)的注冊(cè):signal()和sigaction()。
2.signal()
signal()的函數(shù)原型如下:
void (*signal(int signum, void (*handler)(int)))(int);
在使用該調(diào)用的進(jìn)程中加入以下頭文件:
#include
上述聲明格式比較復(fù)雜,如果不清楚如何使用,也可以通過(guò)下面這種類(lèi)型定義的格式來(lái)使用(POSIX的定義):
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
但這種格式在不同的系統(tǒng)中有不同的類(lèi)型定義,所以要使用這種格式,最好還是參考一下手冊(cè)。在調(diào)用中,參數(shù)signum指出要設(shè)置處理方法的信號(hào)。第二個(gè)參數(shù)handler是一個(gè)處理函數(shù),或者是
SIG_IGN:忽略參數(shù)signum所指的信號(hào)。
SIG_DFL:恢復(fù)參數(shù)signum所指信號(hào)的處理方法為默認(rèn)值。
傳遞給信號(hào)處理例程的整數(shù)參數(shù)是信號(hào)值,這樣可以使得一個(gè)信號(hào)處理例程處理多個(gè)信號(hào)。系統(tǒng)調(diào)用signal()返回值是指定信號(hào)signum前一次的處理例程或者錯(cuò)誤時(shí)返回錯(cuò)誤代碼SIG_ERR。
signal()通過(guò)系統(tǒng)調(diào)用sys_signal()為一個(gè)指定的信號(hào)設(shè)置用戶態(tài)處理函數(shù)。sys_signal()定義如下:
/*
* For backwards compatibility.? Functionality superseded by sigaction.
*/
asmlinkage unsigned long
sys_signal(int sig, __sighandler_t handler)
{
struct k_sigaction new_sa, old_sa;
int ret;
new_sa.sa.sa_handler = handler;
new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
ret = do_sigaction(sig, &new_sa, &old_sa);
return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
}
__sighandler_t的定義如下:
typedef void __signalfn_t(int);
typedef __signalfn_t __user *__sighandler_t;
信號(hào)由sys_signal()的第一個(gè)參數(shù)指定,信號(hào)處理函數(shù)的地址由第二個(gè)參數(shù)指定。sys_signal()根據(jù)這兩個(gè)參數(shù)設(shè)置一個(gè)k_sigaction結(jié)構(gòu),然后調(diào)用do_sigaction(),該函數(shù)的定義我們會(huì)在后面具體講解。
2.sigaction()
sigaction()的函數(shù)原型如下:
sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
sigaction()對(duì)應(yīng)的系統(tǒng)調(diào)用為do_sigaction(),下面我們具體講解do_sigaction()函數(shù),其定義如下:
2.1do_sigaction()
int
do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
{
struct k_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)) {
/*
* If there might be a fatal signal pending on multiple
* threads, make sure we take it before changing the action.
*/
spin_unlock_irq(¤tt->sighand->siglock);
return -ERESTARTNOINTR;
}
if (oact)//把原來(lái)的k_sigaction保存到oact結(jié)構(gòu)中,這里是對(duì)整個(gè)數(shù)據(jù)結(jié)構(gòu)進(jìn)行復(fù)制
*oact = *k;
if (act) {
/*
* POSIX 3.3.1.3:
*? "Setting a signal action to SIG_IGN for a signal that is
*? pending shall cause the pending signal to be discarded,
*? whether or not it is blocked."
*
*? "Setting a signal action to SIG_DFL for a signal that is
*? pending and whose default action is to ignore the signal
*? (for example, SIGCHLD), shall cause the pending signal to
*? be discarded, whether or not it is blocked"
*/
if (act->sa.sa_handler == SIG_IGN ||
(act->sa.sa_handler == SIG_DFL &&
sig_kernel_ignore(sig))) {
/*
* This is a fairly rare case, so we only take the
* tasklist_lock once we're sure we'll need it.
* Now we must do this little unlock and relock
* dance to maintain the lock hierarchy.
*/
struct task_struct *t = current;
spin_unlock_irq(&t->sighand->siglock);
read_lock(&tasklist_lock);
spin_lock_irq(&t->sighand->siglock);
*k = *act; //把新的k_sigaction結(jié)構(gòu)復(fù)制到進(jìn)程的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_thread(t);
} while (t != current);
spin_unlock_irq(¤t->sighand->siglock);
read_unlock(&tasklist_lock);
return 0;
}
*k = *act; //把新的k_sigaction結(jié)構(gòu)復(fù)制到進(jìn)程的sighand->action中
sigdelsetmask(&k->sa.sa_mask,
sigmask(SIGKILL) | sigmask(SIGSTOP));
}
spin_unlock_irq(¤tt->sighand->siglock);
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的linux内核层是什么,从用户层到内核层 - Linux内核中的信号机制_Linux编程_Linux公社-Linux系统门户网站...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 海通证券开户用什么交易软件?
- 下一篇: linux系统如何查看是否是线程死锁,多