国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 操作系統(tǒng) > 正文

深入理解進(jìn)程間通信之信號(hào)

2024-06-28 13:19:42
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
深入理解進(jìn)程間通信之信號(hào)信號(hào)及信號(hào)源

信號(hào)本質(zhì)

  信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,在原理上,一個(gè)進(jìn)程收到一個(gè)信號(hào)與處理器收到一個(gè)中斷請(qǐng)求可以說(shuō)是一樣的。信號(hào)是異步的,一個(gè)進(jìn)程不必通過(guò)任何操作來(lái)等待信號(hào)的到達(dá),事實(shí)上,進(jìn)程也不知道信號(hào)到底什么時(shí)候到達(dá)。

  信號(hào)是進(jìn)程間通信機(jī)制中唯一的異步通信機(jī)制,可以看作是異步通知,通知接收信號(hào)的進(jìn)程有哪些事情發(fā)生了。信號(hào)機(jī)制經(jīng)過(guò)POSIX實(shí)時(shí)擴(kuò)展后,功能更加強(qiáng)大,除了基本通知功能外,還可以傳遞附加信息。

信號(hào)來(lái)源

  信號(hào)事件的發(fā)生有兩個(gè)來(lái)源:硬件來(lái)源(比如我們按下了鍵盤(pán)或者其它硬件故障);軟件來(lái)源,最常用發(fā)送信號(hào)的系統(tǒng)函數(shù)是kill, raise, alarm和setitimer以及sigqueue函數(shù),軟件來(lái)源還包括一些非法運(yùn)算等操作。

信號(hào)的種類(lèi)

  系統(tǒng)支持的所有信號(hào)如下所示:

  進(jìn)程可以屏蔽掉大多數(shù)信號(hào),除了SIGSTOP和SIGKILL。

進(jìn)程對(duì)信號(hào)的響應(yīng)

  進(jìn)程可以通過(guò)三種方式來(lái)響應(yīng)一個(gè)信號(hào):(1)忽略信號(hào),即對(duì)信號(hào)不做任何處理,其中,有兩個(gè)信號(hào)不能忽略:SIGKILL及SIGSTOP;(2)捕捉信號(hào)。定義信號(hào)處理函數(shù),當(dāng)信號(hào)發(fā)生時(shí),執(zhí)行相應(yīng)的處理函數(shù);(3)執(zhí)行缺省操作,linux對(duì)每種信號(hào)都規(guī)定了默認(rèn)操作。注意,進(jìn)程對(duì)實(shí)時(shí)信號(hào)的缺省反應(yīng)是進(jìn)程終止。

  Linux究竟采用上述三種方式的哪一個(gè)來(lái)響應(yīng)信號(hào),取決于傳遞給相應(yīng)API函數(shù)的參數(shù)。

信號(hào)的安裝

  如果進(jìn)程要處理某一信號(hào),那么就要在進(jìn)程中安裝該信號(hào)。安裝信號(hào)主要用來(lái)確定信號(hào)值及進(jìn)程針對(duì)該信號(hào)值的動(dòng)作之間的映射關(guān)系,即進(jìn)程將要處理哪個(gè)信號(hào);該信號(hào)被傳遞給進(jìn)程時(shí),將執(zhí)行何種操作。

  Linux主要有兩個(gè)函數(shù)實(shí)現(xiàn)信號(hào)的安裝:signal()、sigaction()。其中signal()在可靠信號(hào)系統(tǒng)調(diào)用的基礎(chǔ)上實(shí)現(xiàn), 是庫(kù)函數(shù)。它只有兩個(gè)參數(shù),不支持信號(hào)傳遞信息,主要是用于前32種非實(shí)時(shí)信號(hào)的安裝;而sigaction()是較新的函數(shù)(由兩個(gè)系統(tǒng)調(diào)用實(shí)現(xiàn):sys_signal以及sys_rt_sigaction),有三個(gè)參數(shù),支持信號(hào)傳遞信息,主要用來(lái)與 sigqueue() 系統(tǒng)調(diào)用配合使用,當(dāng)然,sigaction()同樣支持非實(shí)時(shí)信號(hào)的安裝。sigaction()優(yōu)于signal()主要體現(xiàn)在支持信號(hào)帶有參數(shù)。

signal
  typedef void (*sighandler_t)(int);  sighandler_t signal(int signum, sighandler_t handler));

  第一個(gè)參數(shù)指定信號(hào)的值,第二個(gè)參數(shù)指定針對(duì)前面信號(hào)值的處理,可以忽略該信號(hào)(參數(shù)設(shè)為SIG_IGN);可以采用系統(tǒng)默認(rèn)方式處理信號(hào)(參數(shù)設(shè)為SIG_DFL);也可以自己實(shí)現(xiàn)處理方式(參數(shù)指定一個(gè)函數(shù)地址)。

  如果signal()調(diào)用成功,返回最后一次為安裝信號(hào)signum而調(diào)用signal()時(shí)的handler值;失敗則返回SIG_ERR。

sigaction
  int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));

  sigaction函數(shù)用于改變進(jìn)程接收到特定信號(hào)后的行為。該函數(shù)的第一個(gè)參數(shù)為信號(hào)的值,可以為除SIGKILL及SIGSTOP外的任何一個(gè)特定有效的信號(hào)(為這兩個(gè)信號(hào)定義自己的處理函數(shù),將導(dǎo)致信號(hào)安裝錯(cuò)誤)。第二個(gè)參數(shù)是指向結(jié)構(gòu)sigaction的一個(gè)實(shí)例的指針,在結(jié)構(gòu) sigaction的實(shí)例中,指定了對(duì)特定信號(hào)的處理,可以為空,進(jìn)程會(huì)以缺省方式對(duì)信號(hào)處理;第三個(gè)參數(shù)oldact指向的對(duì)象用來(lái)保存原來(lái)對(duì)相應(yīng)信號(hào)的處理,可指定oldact為NULL。如果把第二、第三個(gè)參數(shù)都設(shè)為NULL,那么該函數(shù)可用于檢查信號(hào)的有效性。

  第二個(gè)參數(shù)最為重要,其中包含了對(duì)指定信號(hào)的處理、信號(hào)所傳遞的信息、信號(hào)處理函數(shù)執(zhí)行過(guò)程中應(yīng)屏蔽掉哪些函數(shù)等等。

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

  發(fā)送信號(hào)的主要函數(shù)有:kill()、raise()、 sigqueue()、alarm()、setitimer()以及abort()。

kill
  int kill(pid_t pid, int signo);

  signo是信號(hào)值,當(dāng)為0時(shí)(即空信號(hào)),實(shí)際不發(fā)送任何信號(hào),但照常進(jìn)行錯(cuò)誤檢查,因此,可用于檢查目標(biāo)進(jìn)程是否存在,以及當(dāng)前進(jìn)程是否具有向目標(biāo)發(fā)送信號(hào)的權(quán)限(root權(quán)限的進(jìn)程可以向任何進(jìn)程發(fā)送信號(hào),非root權(quán)限的進(jìn)程只能向?qū)儆谕粋€(gè)session或者同一個(gè)用戶(hù)的進(jìn)程發(fā)送信號(hào))。

raise
  int raise(int signo);

  向進(jìn)程本身發(fā)送信號(hào),參數(shù)為即將發(fā)送的信號(hào)值。調(diào)用成功返回 0;否則,返回 -1。

sigqueue
  int sigqueue(pid_t pid, int signo, const union sigval val);

  sigqueue()與函數(shù)sigaction()配合使用,sigqueue的第一個(gè)參數(shù)是指定接收信號(hào)的進(jìn)程ID,第二個(gè)參數(shù)確定即將發(fā)送的信號(hào),第三個(gè)參數(shù)是一個(gè)聯(lián)合數(shù)據(jù)結(jié)構(gòu)union sigval,指定了信號(hào)傳遞的參數(shù),即通常所說(shuō)的4字節(jié)值。

  sigqueue()比kill()傳遞了更多的附加信息,但sigqueue()只能向一個(gè)進(jìn)程發(fā)送信號(hào),而不能發(fā)送信號(hào)給一個(gè)進(jìn)程組。如果signo=0,將會(huì)執(zhí)行錯(cuò)誤檢查,但實(shí)際上不發(fā)送任何信號(hào),0值信號(hào)可用于檢查pid的有效性以及當(dāng)前進(jìn)程是否有權(quán)限向目標(biāo)進(jìn)程發(fā)送信號(hào)。在調(diào)用sigqueue時(shí),sigval_t指定的信息會(huì)拷貝到3參數(shù)信號(hào)處理函數(shù)(3參數(shù)信號(hào)處理函數(shù)指的是信號(hào)處理函數(shù)由 sigaction安裝,并設(shè)定了sa_sigaction指針)的siginfo_t結(jié)構(gòu)中,這樣信號(hào)處理函數(shù)就可以處理這些信息了。由于 sigqueue系統(tǒng)調(diào)用支持發(fā)送帶參數(shù)信號(hào),所以比kill()系統(tǒng)調(diào)用的功能要靈活和強(qiáng)大得多。

  注:sigqueue()發(fā)送非實(shí)時(shí)信號(hào)時(shí),第三個(gè)參數(shù)包含的信息仍然能夠傳遞給信號(hào)處理函數(shù); sigqueue()發(fā)送非實(shí)時(shí)信號(hào)時(shí),仍然不支持排隊(duì),即在信號(hào)處理函數(shù)執(zhí)行過(guò)程中到來(lái)的所有相同信號(hào),都被合并為一個(gè)信號(hào)。

alarm
  unsigned int alarm(unsigned int seconds);

  專(zhuān)門(mén)為SIGALRM信號(hào)而設(shè),在指定的時(shí)間seconds秒后,將向進(jìn)程本身發(fā)送SIGALRM信號(hào),又稱(chēng)為鬧鐘時(shí)間。進(jìn)程調(diào)用alarm后,任何以前的alarm()調(diào)用都將無(wú)效。如果參數(shù)seconds為零,那么進(jìn)程內(nèi)將不再包含任何鬧鐘時(shí)間。返回值,如果調(diào)用alarm()前,進(jìn)程中已經(jīng)設(shè)置了鬧鐘時(shí)間,則返回上一個(gè)鬧鐘時(shí)間的剩余時(shí)間,否則返回0。

settimer
  int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));

  setitimer()比alarm功能強(qiáng)大,支持3種類(lèi)型的定時(shí)器:

  • ITIMER_REAL: 設(shè)定絕對(duì)時(shí)間;經(jīng)過(guò)指定的時(shí)間后,內(nèi)核將發(fā)送SIGALRM信號(hào)給本進(jìn)程;
  • ITIMER_VIRTUAL 設(shè)定程序執(zhí)行時(shí)間;經(jīng)過(guò)指定的時(shí)間后,內(nèi)核將發(fā)送SIGVTALRM信號(hào)給本進(jìn)程;
  • ITIMER_PROF 設(shè)定進(jìn)程執(zhí)行以及內(nèi)核因本進(jìn)程而消耗的時(shí)間和,經(jīng)過(guò)指定的時(shí)間后,內(nèi)核將發(fā)送ITIMER_VIRTUAL信號(hào)給本進(jìn)程;

  setitimer()第一個(gè)參數(shù)which指定定時(shí)器類(lèi)型(上面三種之一);第二個(gè)參數(shù)是結(jié)構(gòu)itimerval的一個(gè)實(shí)例;第三個(gè)參數(shù)可不做處理。setitimer()調(diào)用成功返回0,否則返回-1。

abort
  void abort(void); 

  向進(jìn)程發(fā)送SIGABORT信號(hào),默認(rèn)情況下進(jìn)程會(huì)異常退出,當(dāng)然可定義自己的信號(hào)處理函數(shù)。即使SIGABORT被進(jìn)程設(shè)置為阻塞信號(hào),調(diào)用abort()后,SIGABORT仍然能被進(jìn)程接收。該函數(shù)無(wú)返回值。

信號(hào)生命周期

  對(duì)于一個(gè)完整的信號(hào)生命周期(從信號(hào)發(fā)送到相應(yīng)的處理函數(shù)執(zhí)行完畢)來(lái)說(shuō),可以分為三個(gè)重要的階段,這三個(gè)階段由四個(gè)重要事件來(lái)刻畫(huà):信號(hào)誕生;信號(hào)在進(jìn)程中注冊(cè)完畢;信號(hào)在進(jìn)程中的注銷(xiāo)完畢;信號(hào)處理函數(shù)執(zhí)行完畢。


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宁阳县| 全南县| 佛山市| 开封县| 视频| 黄石市| 易门县| 新津县| 临洮县| 镇沅| 略阳县| 景洪市| 石楼县| 芦溪县| 咸丰县| 青河县| 西贡区| 新竹县| 河东区| 喜德县| 肇东市| 长武县| 东台市| 石景山区| 商水县| 蓬溪县| 彝良县| 丹棱县| 都匀市| 小金县| 新邵县| 依兰县| 霍州市| 彰化县| 民县| 巴楚县| 南皮县| 栾川县| 福建省| 遂川县| 龙门县|