溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

linux signal的作用是什么

發(fā)布時(shí)間:2023-04-19 09:48:47 來源:億速云 閱讀:102 作者:iii 欄目:建站服務(wù)器

本文小編為大家詳細(xì)介紹“l(fā)inux signal的作用是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“l(fā)inux signal的作用是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識(shí)吧。

linux signal用來通知進(jìn)程某個(gè)特定事件的發(fā)生或者是讓進(jìn)程執(zhí)行某個(gè)特定的處理函數(shù);signal即信號(hào),是Unix家族中一個(gè)古老的通信機(jī)制;信號(hào)可以來自終端的鍵盤字符輸入,比如control-C觸發(fā)的SIGINIT,也可以來自與硬件或軟件有關(guān)的異常,比如應(yīng)用程序訪問了無效地址觸發(fā)的SIGSEGV,定時(shí)器到期觸發(fā)的SIGALARM等。

linux signal用來做什么?

Linux中的信號(hào)處理機(jī)制

信號(hào)(Signal)是Unix家族中一個(gè)古老的通信機(jī)制,主要用來通知進(jìn)程某個(gè)特定事件的發(fā)生,或者是讓進(jìn)程執(zhí)行某個(gè)特定的處理函數(shù)。說它古老,是因?yàn)樗诘谝淮鶸nix系統(tǒng)中就已經(jīng)存在了。

信號(hào)的發(fā)送

信號(hào)可以來自終端(terminal)的鍵盤字符輸入,比如control-C觸發(fā)的SIGINIT;也可以來自與硬件或軟件有關(guān)的異常,比如應(yīng)用程序訪問了無效地址觸發(fā)的SIGSEGV(segmentation fault),定時(shí)器到期觸發(fā)的SIGALARM等。這些信號(hào)都是由內(nèi)核發(fā)送給進(jìn)程的。

進(jìn)程收到的信號(hào)還可以來自于其他進(jìn)程。但不是所有的進(jìn)程都可以向其他任意一個(gè)進(jìn)程發(fā)送信號(hào),只有具有root權(quán)限的super user才可以這么做,對(duì)于普通user的進(jìn)程,只能向?qū)儆谕籾ser的進(jìn)程發(fā)送信號(hào)。

那進(jìn)程可以向內(nèi)核發(fā)送信號(hào)嗎?可以是可以,但內(nèi)核線程是不會(huì)響應(yīng)的,發(fā)了也白發(fā),除非……你修改內(nèi)核代碼。

通常信號(hào)被認(rèn)為是一種異步的機(jī)制,但是在Linux的代碼中,以下由異常引起的信號(hào)也被稱為"synchronous"的:

#define SYNCHRONOUS_MASK \	(sigmask(SIGSEGV) | sigmask(SIGBUS) | sigmask(SIGILL) | \	 sigmask(SIGTRAP) | sigmask(SIGFPE) | sigmask(SIGSYS))

這里我們稱接收信號(hào)的進(jìn)程為“目標(biāo)進(jìn)程”。傳統(tǒng)的信號(hào)發(fā)送函數(shù)是kill(),這名字看起來好嚇人,感覺好像是目標(biāo)進(jìn)程馬上就要被“殺”掉了。事實(shí)上,雖然各路信號(hào)都用kill()來發(fā)送,但真正要"kill"掉進(jìn)程的,只占一小部分。當(dāng)然,現(xiàn)在已經(jīng)有了功能更強(qiáng),名字也更友好的sigqueue()了。

來看下兩者的函數(shù)原型:

int kill(pid_t pid, int sig);int sigqueue(pid_t pid, int sig, const union sigval value);

pid代表目標(biāo)進(jìn)程的PID。Linux中進(jìn)程的PID都是正數(shù),那參數(shù)pid的值如果是0或者負(fù)數(shù),是不是就是非法的呢?非也,事實(shí)上,0和負(fù)數(shù)在這里都是有其他用途的。Linux里有個(gè)進(jìn)程組的概念(process group),表示一類進(jìn)程的集合。在kill()中,參數(shù)pid為"0"說明信號(hào)是發(fā)給當(dāng)前進(jìn)程所在進(jìn)程組的所有進(jìn)程,小于"-1"則是向編號(hào)為-pid的進(jìn)程組發(fā)送信號(hào)。

__kill_pgrp_info(sig, info, pid ? find_vpid(-pid) : task_pgrp(current));

pid為"-1"表示發(fā)送給除Init進(jìn)程和自身以外的所有進(jìn)程,或者說是除自身以外的所有pid大于1的進(jìn)程。

for_each_process(p) {
if (task_pid_vnr(p) > 1 && !same_thread_group(p, current))
           ...

如果這里pid是進(jìn)程自己的PID,那么就是進(jìn)程給自身發(fā)送信號(hào)。為此,Linux還提供了一個(gè)更簡潔的接口:raise()函數(shù)。

kill(getpid(), sig) --> raise(sig)

需要注意的是,在sigqueue()中,不能通過將參數(shù)pid的值設(shè)為負(fù)數(shù)來向整個(gè)進(jìn)程組發(fā)送信號(hào)。

sig代表要發(fā)送信號(hào)的編號(hào),Linux中的信號(hào)編號(hào)是從1開始的,那參數(shù)sig的值如果為0會(huì)怎樣呢?這里的0也有妙用,sig為"0"時(shí)并不會(huì)真正的往目標(biāo)進(jìn)程(或進(jìn)程組)發(fā)送信號(hào),而是用來檢測目標(biāo)進(jìn)程(或進(jìn)程組)是否存在。

至于sigqueue增加的第三個(gè)參數(shù),其定義是這樣的:

union sigval {
int sival_int;
void __user *sival_ptr;};

傳統(tǒng)的信號(hào)是沒有傳遞消息的功能的,sigval算是稍微擴(kuò)展了一下信號(hào)的通信能力。比如,通信雙方可以事先約定某些事件為特定的int值,這個(gè)"sival_int"就可以用來保存具體的int值,目標(biāo)進(jìn)程可以據(jù)此來區(qū)分不同的事件,做出不同的響應(yīng)。當(dāng)然,這種方法傳遞的消息內(nèi)容受限,且不易擴(kuò)展,因而不適合用作常規(guī)的通信手段。

信號(hào)的內(nèi)核處理

就算是進(jìn)程之間發(fā)送信號(hào),那也是要經(jīng)過內(nèi)核的,可以理解成是被內(nèi)核“截獲”了吧。

linux signal的作用是什么

由于內(nèi)核態(tài)和用戶態(tài)的切換操作在不同的硬件體系架構(gòu)上是不同的,而且有一些信號(hào),比如SIGCHLD和SIGSTOP,其實(shí)現(xiàn)也是和架構(gòu)相關(guān)的,所以Linux中signal機(jī)制的很多代碼都是放在架構(gòu)相關(guān)的目錄下的,比如"/arch/arm/kernel/signal.c"。

一個(gè)信號(hào)的相關(guān)信息在內(nèi)核中用siginfo_t結(jié)構(gòu)體表示:

siginfo_t{
   int si_signo;
   int si_sicode;
   union __sifields _sifields;
   ...}
  • si_signo是信號(hào)的編號(hào),從1到64的值都是合法的。

  • si_sicode記錄了信號(hào)的來源,比如SI_USER表示信號(hào)是由進(jìn)程調(diào)用kill()發(fā)出的,SI_QUEUE是由進(jìn)程調(diào)用sigqueue()發(fā)出的,SI_KERNEL則說明該信號(hào)由內(nèi)核產(chǎn)生的。

  • _sifields對(duì)不同的信號(hào)會(huì)有不同的含義,通常包括信號(hào)發(fā)送進(jìn)程的si_pid,發(fā)送進(jìn)程所屬user的si_uid等。對(duì)于由sigqueue()發(fā)送的信號(hào),還包括"sigval "參數(shù)所攜帶的附加信息。

內(nèi)核在截獲到一個(gè)進(jìn)程發(fā)送的信號(hào)后,會(huì)首先做一系列的檢查,比如該信號(hào)的值是否合法啦,進(jìn)程有沒有發(fā)送這個(gè)信號(hào)的權(quán)限啦。如果檢查通過,就調(diào)用copy_from_user()將該信號(hào)的相關(guān)信息復(fù)制到siginfo_t結(jié)構(gòu)體中。

讀到這里,這篇“l(fā)inux signal的作用是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI