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

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

信號之signal函數(shù)

2024-06-28 13:28:30
字體:
供稿:網(wǎng)友
信號之signal函數(shù)

UNIX系統(tǒng)的信號機制最簡單的接口是signal函數(shù)。signal函數(shù)的功能:為指定的信號安裝一個新的信號處理函數(shù)。

#include <signal.h>void (*signal(int signo, void (*func)(int)))(int);

復(fù)雜原型分開看:

void (*signal( int signo, void (*func)(int) ) )(int);

函數(shù)名 :signal

函數(shù)參數(shù) :int signo, void (*func)(int)

返回值類型:void (*)(int);

signo參數(shù)是信號名(參見:http://www.CUOXin.com/nufangrensheng/p/3514157.html中UNIX系統(tǒng)信號Signal欄下的信號名)。func的值是常量SIG_IGN、常量SIG_DFL或當接到此信號后要調(diào)用的函數(shù)的地址。如果指定SIG_IGN,則向內(nèi)核表示忽略此信號(記住有兩個信號SIGKILL和SIGSTOP不能忽略)。如果指定SIG_DFL,則表示接到此信號后的動作是系統(tǒng)默認動作。當指定函數(shù)地址時,則在信號發(fā)生時,調(diào)用該函數(shù),我們稱這種處理為“捕捉”該信號。稱此函數(shù)為信號處理程序(signal handler)或信號捕捉函數(shù)(signal-catching function)。

signal的返回值是指向之前的信號處理程序的指針。(之前的信號處理程序,也就是在執(zhí)行signal(signo,func)之前,對信號signo的信號處理程序)

開頭所示的signal函數(shù)原型太復(fù)雜了,如果使用下面的typedef,則可使其簡單一些:

typedef void Sigfunc(int);

然后,可將signal函數(shù)原型寫成:

Sigfunc *signal(int,Sigfunc *);

如果查看系統(tǒng)的頭文件<signal.h>,則很可能會找到下列形式的聲明:

#define    SIG_ERR        ( void (*) () )-1#define    SIG_DFL        ( void (*) () )0#define    SIG_IGN        ( void (*) () )1

這些常量可用于代替“指向函數(shù)的指針,該函數(shù)需要一個整型參數(shù),而且無返回值”。signal的第二個參數(shù)及其返回值就可用它們表示。這些常量所使用的三個值不一定是-1,0和1。但大多數(shù)UNIX系統(tǒng)都使用上面所示的值。

程序清單10-1 捕捉SIGUSR1和SIGUSR2的簡單程序

#include "apue.h"static void sig_usr(int);    /* one handler for both signals */intmain(void){    if(signal(SIGUSR1, sig_usr) == SIG_ERR)        err_sys("can't catch SIGUSR1");    if(signal(SIGUSR2, sig_usr) == SIG_ERR)        err_sys("can't catch SIGUSR2");    for(;;)        pause();}static voidsig_usr(int signo)    /* argument is signal number */{    if(signo == SIGUSR1)        PRintf("received SIGUSR1/n");    else if (signo == SIGUSR2)        printf("received SIGUSR2/n");    else        err_dump("received signal %d/n", signo);}

pause函數(shù),它使調(diào)用進程在接到一個信號前掛起。

我們在后臺運行該程序,并且用kill(1)命令將信號傳送給它。注意,在UNIX中,殺死(kill)這個術(shù)語是不恰當?shù)摹?strong>kill(1)命令和kill(2)函數(shù)只是將一個信號送給一個進程或進程組。信號是否終止進程則取決于信號的類型,以及進程是否安排了捕捉該信號。

未命名

因為執(zhí)行程序清單10-1的進程不捕捉SIGTERM信號,而針對該信號的系統(tǒng)默認動作是終止,所以當該進程發(fā)送SIGTERM信號后,該進程就會終止。

1、程序啟動

當執(zhí)行一個程序時,所有信號的狀態(tài)都是系統(tǒng)默認或忽略。通常所有信號都被設(shè)置為它們的默認動作,除非調(diào)用exec的進程忽略該信號。確切地講,exec函數(shù)將原先設(shè)置為要捕捉的信號都更改為它們的默認動作,其他信號的狀態(tài)則不變(對于一個進程原先要捕捉的信號,當其執(zhí)行一個新程序后,就自然不能再捕捉它了,因為信號捕捉函數(shù)的地址很可能在所執(zhí)行的新程序文件中無意義)。

一個具體的例子是一個交互式shell如何處理針對后臺進程的中斷和退出信號。對于一個非作業(yè)控制shell,當在后臺執(zhí)行一個進程時,例如:

cc main.c &

shell自動將后臺進程中對中斷和退出信號的處理方式設(shè)置為忽略。于是,當按中斷鍵時就不會影響到后臺進程。如果沒有執(zhí)行這樣的處理,那么當按中斷鍵時,它不但會終止前臺進程,還會終止所有后臺進程。

很多捕捉這兩個信號的交互式程序具有下列形式的代碼:

void sig_int(int), sig_quit(int);if(signal(SIGINT, SIG_IGN) != SIG_IGN)    signal(SIGINT, sig_int);if(signal(SIGQUIT, SIG_IGN) != SIG_IGN)    signal(SIGQUIT, sig_quit);

這樣處理后,僅當信號當前未被忽略時,進程才會捕捉它們。

從signal的這兩種調(diào)用中也可以看到這種函數(shù)的限制:不改變信號的處理方式就不能確定信號的當前處理方式。

2、進程創(chuàng)建

當一個進程調(diào)用fork時,其子進程繼承父進程的信號處理方式。因為子進程在開始時復(fù)制了父進程的存儲映像,所以信號捕捉函數(shù)的地址在子進程中是有意義的。

本篇博文內(nèi)容摘自《UNIX環(huán)境高級編程》(第二版),僅作個人學習記錄所用。關(guān)于本書可參考:http://www.apuebook.com/


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙口市| 囊谦县| 江西省| 墨竹工卡县| 蓝山县| 永修县| 会昌县| 琼中| 紫云| 大连市| 汉寿县| 孝昌县| 娱乐| 双江| 高邑县| 育儿| 汶上县| 绥江县| 曲周县| 南木林县| 淮滨县| 库伦旗| 竹山县| 南川市| 南汇区| 嘉禾县| 株洲县| 扎囊县| 尉犁县| 陆丰市| 红原县| 新津县| 武宣县| 沾益县| 大安市| 监利县| 四川省| 广西| 葵青区| 手游| 霍州市|