您好,登錄后才能下訂單哦!
這篇文章主要介紹了Linux的Signal機(jī)制是什么的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡(jiǎn)單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇Linux的Signal機(jī)制是什么文章都會(huì)有所收獲,下面我們一起來(lái)看看吧。
Signal機(jī)制在Linux中是一個(gè)非常常用的進(jìn)程間通信機(jī)制,很多人在使用的時(shí)候不會(huì)考慮該機(jī)制是具體如何實(shí)現(xiàn)的。signal機(jī)制可以被理解成進(jìn)程的軟中斷,因此,在實(shí)時(shí)性方面還是相對(duì)比較高的。
信號(hào)的名字和編號(hào): 每個(gè)信號(hào)都有一個(gè)名字和編號(hào),這些名字都以“SIG”開(kāi)頭,例如“SIGIO ”、“SIGCHLD”等等。 信號(hào)定義在signal.h
頭文件中,信號(hào)名都定義為正整數(shù)。 具體的信號(hào)名稱可以使用kill -l
來(lái)查看信號(hào)的名字以及序號(hào),信號(hào)是從1開(kāi)始編號(hào)的,不存在0號(hào)信號(hào)。kill對(duì)于信號(hào)0又特殊的應(yīng)用。
信號(hào)的名稱
信號(hào)的處理: 信號(hào)的處理有三種方法,分別是:忽略、捕捉和默認(rèn)動(dòng)作
SIGKILL
和SIGSTOP
)。因?yàn)樗麄兿騼?nèi)核和超級(jí)用戶提供了進(jìn)程終止和停止的可靠方法,如果忽略了,那么這個(gè)進(jìn)程就變成了沒(méi)人能管理的的進(jìn)程,顯然是內(nèi)核設(shè)計(jì)者不希望看到的場(chǎng)景man 7 signal
來(lái)查看系統(tǒng)的具體定義。在此,我就不詳細(xì)展開(kāi)了,需要查看的,可以自行查看。也可以參考 《UNIX 環(huán)境高級(jí)編程(第三部)》的 P251——P256中間對(duì)于每個(gè)信號(hào)有詳細(xì)的說(shuō)明。了解了信號(hào)的概述,那么,信號(hào)是如何來(lái)使用呢?
?
其實(shí)對(duì)于常用的 kill 命令就是一個(gè)發(fā)送信號(hào)的工具,
kill 9 PID
來(lái)殺死進(jìn)程。比如,我在后臺(tái)運(yùn)行了一個(gè) top 工具,通過(guò) ps 命令可以查看他的 PID,通過(guò) kill 9 來(lái)發(fā)送了一個(gè)終止進(jìn)程的信號(hào)來(lái)結(jié)束了 top 進(jìn)程。如果查看信號(hào)編號(hào)和名稱,可以發(fā)現(xiàn)9對(duì)應(yīng)的是 9) SIGKILL,正是殺死該進(jìn)程的信號(hào)。而以下的執(zhí)行過(guò)程實(shí)際也就是執(zhí)行了9號(hào)信號(hào)的默認(rèn)動(dòng)作——殺死進(jìn)程。kill 殺死進(jìn)程
對(duì)于信號(hào)來(lái)說(shuō),最大的意義不是為了殺死信號(hào),而是實(shí)現(xiàn)一些異步通訊的手段,那么如何來(lái)自定義信號(hào)的處理函數(shù)呢?
信號(hào)處理函數(shù)的注冊(cè)不只一種方法,分為入門版和高級(jí)版
signal
sigaction
信號(hào)發(fā)送函數(shù)也不止一個(gè),同樣分為入門版和高級(jí)版 1.入門版:kill 2.高級(jí)版:sigqueue
在正式開(kāi)始了解這兩個(gè)函數(shù)之前,可以先來(lái)思考一下,處理中斷都需要處理什么問(wèn)題。 按照我們之前思路來(lái)看,可以發(fā)送的信號(hào)類型是多種多樣的,每種信號(hào)的處理可能不一定相同,那么,我們肯定需要知道到底發(fā)生了什么信號(hào)。 另外,雖然我們知道了系統(tǒng)發(fā)出來(lái)的是哪種信號(hào),但是還有一點(diǎn)也很重要,就是系統(tǒng)產(chǎn)生了一個(gè)信號(hào),是由誰(shuí)來(lái)響應(yīng)? 如果系統(tǒng)通過(guò) ctrl+c 產(chǎn)生了一個(gè) SIGINT(中斷信號(hào)),顯然不是所有程序同時(shí)結(jié)束,那么,信號(hào)一定需要有一個(gè)接收者。對(duì)于處理信號(hào)的程序來(lái)說(shuō),接收者就是自己。
開(kāi)始的時(shí)候,先來(lái)看看入門版本的信號(hào)注冊(cè)函數(shù),他的函數(shù)原型如下: signal 的函數(shù)原型
#include typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);
根據(jù)函數(shù)原型可以看出由兩部分組成,一個(gè)是真實(shí)處理信號(hào)的函數(shù),另一個(gè)是注冊(cè)函數(shù)了。 對(duì)于sighandler_t signal(int signum, sighandler_t handler);
函數(shù)來(lái)說(shuō),signum 顯然是信號(hào)的編號(hào),handler 是中斷函數(shù)的指針。 同樣,typedef void (*sighandler_t)(int);
中斷函數(shù)的原型中,有一個(gè)參數(shù)是 int 類型,顯然也是信號(hào)產(chǎn)生的類型,方便使用一個(gè)函數(shù)來(lái)處理多個(gè)信號(hào)。我們先來(lái)看看簡(jiǎn)單一個(gè)信號(hào)注冊(cè)的代碼示例吧。
#include#include#include //typedef void (*sighandler_t)(int); void handler(int signum) { if(signum == SIGIO) printf("SIGIO signal: %d\n", signum); else if(signum == SIGUSR1) printf("SIGUSR1 signal: %d\n", signum); else printf("error\n"); } int main(void) { //sighandler_t signal(int signum, sighandler_t handler); signal(SIGIO, handler); signal(SIGUSR1, handler); printf("%d %d\n", SIGIO, SIGUSR1); for(;;) { sleep(10000); } return 0; }
我們先使用 kill 命令發(fā)送信號(hào)給之前所寫的程序,關(guān)于這個(gè)命令,我們后面再談。
通過(guò) kill 命令發(fā)送信號(hào)
程序接收到的信號(hào)的處理結(jié)果
簡(jiǎn)單的總結(jié)一下,我們通過(guò) signal 函數(shù)注冊(cè)一個(gè)信號(hào)處理函數(shù),分別注冊(cè)了兩個(gè)信號(hào)(SIGIO 和 SIGUSER1);隨后主程序就一直“長(zhǎng)眠”了。 通過(guò) kill 命令發(fā)送信號(hào)之前,我們需要先查看到接收者,通過(guò) ps 命令查看了之前所寫的程序的 PID,通過(guò) kill 函數(shù)來(lái)發(fā)送。 對(duì)于已注冊(cè)的信號(hào),使用 kill 發(fā)送都可以正常接收到,但是如果發(fā)送了未注冊(cè)的信號(hào),則會(huì)使得應(yīng)用程序終止進(jìn)程。
那么,已經(jīng)可以設(shè)置信號(hào)處理函數(shù)了,信號(hào)的處理還有兩種狀態(tài),分別是默認(rèn)處理和忽略,這兩種設(shè)置很簡(jiǎn)單,只需要將 handler 設(shè)置為 SIG_IGN(忽略信號(hào))或 SIG_DFL(默認(rèn)動(dòng)作)即可。
在此還有兩個(gè)問(wèn)題需要說(shuō)明一下:
入門版的信號(hào)注冊(cè)還是比較簡(jiǎn)單的,只需要一句注冊(cè)和一個(gè)處理函數(shù)即可,那么,接下來(lái)看看,如何發(fā)送信號(hào)吧。
kill 的函數(shù)原型
#include #include int kill(pid_t pid, int sig);
正如我之前所說(shuō)的,信號(hào)的處理需要有接受者,顯然發(fā)送者必須要知道發(fā)給誰(shuí),根據(jù) kill 函數(shù)的遠(yuǎn)行可以看到,pid 就是接受者的 pid,sig 則是發(fā)送的信號(hào)的類型。從原型來(lái)看,發(fā)送信號(hào)要比接受信號(hào)還要簡(jiǎn)單些,那么我們直接上代碼吧~~!Show me the code!!!
#include #include #include#include int main(int argc, char** argv) { if(3 != argc) { printf("[Arguments ERROR!]\n"); printf("\tUsage:\n"); printf("\t\t%s \n", argv[0]); return -1; } int pid = atoi(argv[1]); int sig = atoi(argv[2]); //int kill(pid_t pid, int sig); if(pid > 0 && sig > 0) { kill(pid, sig); } else { printf("Target_PID or Signal_Number MUST bigger than 0!\n"); } return 0; }
發(fā)送信號(hào)
接收信號(hào)的結(jié)果
總結(jié)一下: 根據(jù)以上的結(jié)果可看到,基本可以實(shí)現(xiàn)了信號(hào)的發(fā)送,雖然不能直接發(fā)送信號(hào)名稱,但是通過(guò)信號(hào)的編號(hào),可以正常的給程序發(fā)送信號(hào)了,也是初步實(shí)現(xiàn)了信號(hào)的發(fā)送流程。
關(guān)于 kill 函數(shù),還有一點(diǎn)需要額外說(shuō)明,上面的程序限定了 pid 必須為大于0的正整數(shù),其實(shí) kill 函數(shù)傳入的 pid 可以是小于等于0的整數(shù)。 pid > 0:將發(fā)送個(gè)該 pid 的進(jìn)程 pid == 0:將會(huì)把信號(hào)發(fā)送給與發(fā)送進(jìn)程屬于同一進(jìn)程組的所有進(jìn)程,并且發(fā)送進(jìn)程具有權(quán)限想這些進(jìn)程發(fā)送信號(hào)。 pid
關(guān)于信號(hào),還有更多的話題,比如,信號(hào)是否都能夠準(zhǔn)確的送達(dá)到目標(biāo)進(jìn)程呢?答案其實(shí)是不一定,那么這就有了可靠信號(hào)和不可靠信號(hào)
不可靠信號(hào):信號(hào)可能會(huì)丟失,一旦信號(hào)丟失了,進(jìn)程并不能知道信號(hào)丟失 可靠信號(hào):也是阻塞信號(hào),當(dāng)發(fā)送了一個(gè)阻塞信號(hào),并且該信號(hào)的動(dòng)作時(shí)系統(tǒng)默認(rèn)動(dòng)作或捕捉該信號(hào),如果信號(hào)從發(fā)出以后會(huì)一直保持未決的狀態(tài),直到該進(jìn)程對(duì)此信號(hào)解除了阻塞,或?qū)?duì)此信號(hào)的動(dòng)作更改為忽略。 對(duì)于信號(hào)來(lái)說(shuō),信號(hào)編號(hào)小于等于31的信號(hào)都是不可靠信號(hào),之后的信號(hào)為可卡信號(hào),系統(tǒng)會(huì)根據(jù)有信號(hào)隊(duì)列,將信號(hào)在遞達(dá)之前進(jìn)行阻塞。
信號(hào)的阻塞和未決是通過(guò)信號(hào)的狀態(tài)字來(lái)管理的,該狀態(tài)字是按位來(lái)管理信號(hào)的狀態(tài)。每個(gè)信號(hào)都有獨(dú)立的阻塞字,規(guī)定了當(dāng)前要阻塞地達(dá)到該進(jìn)程的信號(hào)集。
信號(hào)阻塞狀態(tài)字(block),1代表阻塞、0代表不阻塞;信號(hào)未決狀態(tài)字(pending)的1代表未決,0代表信號(hào)可以抵達(dá)了;它們都是每一個(gè)bit代表一個(gè)信號(hào)
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
函數(shù)來(lái)獲取或者設(shè)置。該函數(shù)管理信號(hào),是通過(guò)信號(hào)集的數(shù)據(jù)結(jié)構(gòu)來(lái)進(jìn)行管理的,信號(hào)集可以通過(guò)以下的函數(shù)進(jìn)行管理。 信號(hào)集操作函數(shù)(狀態(tài)字表示)
#include int sigemptyset(sigset_t *set); //初始化 set 中傳入的信號(hào)集,清空其中所有信號(hào) int sigfillset(sigset_t *set); //把信號(hào)集填1,讓 set 包含所有的信號(hào) int sigaddset(sigset_t *set, int signum);//把信號(hào)集對(duì)應(yīng)位置為1 int sigdelset(sigset_t *set, int signum);//吧信號(hào)集對(duì)應(yīng)位置為0 int sigismember(const sigset_t *set, int signum);//判斷signal是否在信號(hào)集
對(duì)于信號(hào)集分配好內(nèi)存空間,需要使用初始化函數(shù)來(lái)初始化。初始化完成后,可以在該集合中添加、刪除特定的信號(hào)。 int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
其中 how 變量決定了是如何操作該狀態(tài)字。 SIG_BLOCK:set包含了我們希望添加到當(dāng)前信號(hào)阻塞字的信號(hào),相當(dāng)于mask=mask|set SIG_UNBLOCK:set包含了我們希望從當(dāng)前信號(hào)阻塞字中解除阻塞的信號(hào),相當(dāng)于mask=mask&~set SIG_SETMASK:設(shè)置當(dāng)前信號(hào)阻塞字為set所指的值,相當(dāng)于mask=set
pending是由內(nèi)核來(lái)根據(jù)block設(shè)置的,只可以讀取其中的數(shù)據(jù),來(lái)段判斷信號(hào)是否會(huì)遞達(dá)。通過(guò)設(shè)置block可以將希望阻塞的信號(hào)進(jìn)行阻塞,對(duì)應(yīng)的pending會(huì)由內(nèi)核來(lái)設(shè)置
設(shè)置信號(hào)阻塞、未達(dá)的步驟:
sigset bset;
sigemptyset(&bset);
sigaddset(&bset, SIGINT);
sigprocmask(SIG_UNBLOCK, &bset, NULL);
#include int sigpending(sigset_t *set);
這個(gè)函數(shù)使用很簡(jiǎn)單,對(duì)于調(diào)用他的進(jìn)程來(lái)說(shuō),其中信號(hào)集中的信號(hào)是阻塞不能遞送的,那么,也就一定會(huì)是當(dāng)前未決的。
#include int sigsuspend(const sigset_t *mask);
為何會(huì)出現(xiàn)原子性的解除阻塞的函數(shù)呢? 因?yàn)?,?dāng)信號(hào)被阻塞的時(shí)候,產(chǎn)生了信號(hào),那么該信號(hào)的遞送就要推遲到這個(gè)信號(hào)被解除了阻塞為止。如果此時(shí),應(yīng)用程序正好處在,解除 SIGINT 的阻塞和 pause 之間,那么此時(shí),會(huì)產(chǎn)生問(wèn)題,可能永遠(yuǎn) pause 不能夠等到SIGINT 信號(hào)來(lái)打斷他,造成程序永久阻塞在 pause 處。 為了解決這個(gè)問(wèn)題,,需要在一個(gè)原子性的操作來(lái)恢復(fù)信號(hào)的屏蔽字,然后才能讓進(jìn)程進(jìn)入休眠狀態(tài),以保證不會(huì)出現(xiàn)上述的問(wèn)題。
進(jìn)程的信號(hào)屏蔽字設(shè)置為
我們已經(jīng)成功完成了信號(hào)的收發(fā),那么為什么會(huì)有高級(jí)版出現(xiàn)呢?其實(shí)之前的信號(hào)存在一個(gè)問(wèn)題就是,雖然發(fā)送和接收到了信號(hào),可是總感覺(jué)少些什么,既然都已經(jīng)把信號(hào)發(fā)送過(guò)去了,為何不能再攜帶一些數(shù)據(jù)呢? 正是如此,我們需要另外的函數(shù)來(lái)通過(guò)信號(hào)傳遞的過(guò)程中,攜帶一些數(shù)據(jù)。咱么先來(lái)看看發(fā)送的函數(shù)吧。
sigaction 的函數(shù)原型
#include int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); struct sigaction { void (*sa_handler)(int); //信號(hào)處理程序,不接受額外數(shù)據(jù),SIG_IGN 為忽略,SIG_DFL 為默認(rèn)動(dòng)作 void (*sa_sigaction)(int, siginfo_t *, void *); //信號(hào)處理程序,能夠接受額外數(shù)據(jù)和sigqueue配合使用 sigset_t sa_mask;//阻塞關(guān)鍵字的信號(hào)集,可以再調(diào)用捕捉函數(shù)之前,把信號(hào)添加到信號(hào)阻塞字,信號(hào)捕捉函數(shù)返回之前恢復(fù)為原先的值。 int sa_flags;//影響信號(hào)的行為SA_SIGINFO表示能夠接受數(shù)據(jù) }; //回調(diào)函數(shù)句柄sa_handler、sa_sigaction只能任選其一
這個(gè)函數(shù)的原版幫助信息,可以通過(guò)man sigaction
來(lái)查看。
sigaction 是一個(gè)系統(tǒng)調(diào)用,根據(jù)這個(gè)函數(shù)原型,我們不難看出,在函數(shù)原型中,第一個(gè)參數(shù)signum
應(yīng)該就是注冊(cè)的信號(hào)的編號(hào);第二個(gè)參數(shù)act
如果不為空說(shuō)明需要對(duì)該信號(hào)有新的配置;第三個(gè)參數(shù)oldact
如果不為空,那么可以對(duì)之前的信號(hào)配置進(jìn)行備份,以方便之后進(jìn)行恢復(fù)。
在這里額外說(shuō)一下struct sigaction
結(jié)構(gòu)體中的 sa_mask 成員,設(shè)置在其的信號(hào)集中的信號(hào),會(huì)在捕捉函數(shù)調(diào)用前設(shè)置為阻塞,并在捕捉函數(shù)返回時(shí)恢復(fù)默認(rèn)原有設(shè)置。這樣的目的是,在調(diào)用信號(hào)處理函數(shù)時(shí),就可以阻塞默寫信號(hào)了。在信號(hào)處理函數(shù)被調(diào)用時(shí),操作系統(tǒng)會(huì)建立新的信號(hào)阻塞字,包括正在被遞送的信號(hào)。因此,可以保證在處理一個(gè)給定信號(hào)時(shí),如果這個(gè)種信號(hào)再次發(fā)生,那么他會(huì)被阻塞到對(duì)之前一個(gè)信號(hào)的處理結(jié)束為止。
sigaction 的時(shí)效性:當(dāng)對(duì)某一個(gè)信號(hào)設(shè)置了指定的動(dòng)作的時(shí)候,那么,直到再次顯式調(diào)用 sigaction并改變動(dòng)作之前都會(huì)一直有效。
關(guān)于結(jié)構(gòu)體中的 flag 屬性的詳細(xì)配置,在此不做詳細(xì)的說(shuō)明了,只說(shuō)明其中一點(diǎn)。如果設(shè)置為 SA_SIGINFO 屬性時(shí),說(shuō)明了信號(hào)處理程序帶有附加信息,也就是會(huì)調(diào)用 sa_sigaction 這個(gè)函數(shù)指針?biāo)赶虻男盘?hào)處理函數(shù)。否則,系統(tǒng)會(huì)默認(rèn)使用 sa_handler 所指向的信號(hào)處理函數(shù)。在此,還要特別說(shuō)明一下,sa_sigaction 和 sa_handler 使用的是同一塊內(nèi)存空間,相當(dāng)于 union,所以只能設(shè)置其中的一個(gè),不能兩個(gè)都同時(shí)設(shè)置。
關(guān)于void (*sa_sigaction)(int, siginfo_t *, void *);
處理函數(shù)來(lái)說(shuō)還需要有一些說(shuō)明。void*
是接收到信號(hào)所攜帶的額外數(shù)據(jù);而struct siginfo
這個(gè)結(jié)構(gòu)體主要適用于記錄接收信號(hào)的一些相關(guān)信息。
siginfo_t { int si_signo; /* Signal number */ int si_errno; /* An errno value */ int si_code; /* Signal code */ int si_trapno; /* Trap number that caused hardware-generated signal (unused on most architectures) */ pid_t si_pid; /* Sending process ID */ uid_t si_uid; /* Real user ID of sending process */ int si_status; /* Exit value or signal */ clock_t si_utime; /* User time consumed */ clock_t si_stime; /* System time consumed */ sigval_t si_value; /* Signal value */ int si_int; /* POSIX.1b signal */ void *si_ptr; /* POSIX.1b signal */ int si_overrun; /* Timer overrun count; POSIX.1b timers */ int si_timerid; /* Timer ID; POSIX.1b timers */ void *si_addr; /* Memory location which caused fault */ int si_band; /* Band event */ int si_fd; /* File descriptor */ }
其中的成員很多,si_signo 和 si_code 是必須實(shí)現(xiàn)的兩個(gè)成員??梢酝ㄟ^(guò)這個(gè)結(jié)構(gòu)體獲取到信號(hào)的相關(guān)信息。 關(guān)于發(fā)送過(guò)來(lái)的數(shù)據(jù)是存在兩個(gè)地方的,sigval_t si_value這個(gè)成員中有保存了發(fā)送過(guò)來(lái)的信息;同時(shí),在si_int或者si_ptr成員中也保存了對(duì)應(yīng)的數(shù)據(jù)。
那么,kill 函數(shù)發(fā)送的信號(hào)是無(wú)法攜帶數(shù)據(jù)的,我們現(xiàn)在還無(wú)法驗(yàn)證發(fā)送收的部分,那么,我們先來(lái)看看發(fā)送信號(hào)的高級(jí)用法后,我們?cè)賮?lái)看看如何通過(guò)信號(hào)來(lái)攜帶數(shù)據(jù)吧。
#include int sigqueue(pid_t pid, int sig, const union sigval value); union sigval { int sival_int; void *sival_ptr; };
使用這個(gè)函數(shù)之前,必須要有幾個(gè)操作需要完成
sigqueue 函數(shù)只能把信號(hào)發(fā)送給單個(gè)進(jìn)程,可以使用 value 參數(shù)向信號(hào)處理程序傳遞整數(shù)值或者指針值。
sigqueue 函數(shù)不但可以發(fā)送額外的數(shù)據(jù),還可以讓信號(hào)進(jìn)行排隊(duì)(操作系統(tǒng)必須實(shí)現(xiàn)了 POSIX.1的實(shí)時(shí)擴(kuò)展),對(duì)于設(shè)置了阻塞的信號(hào),使用 sigqueue 發(fā)送多個(gè)同一信號(hào),在解除阻塞時(shí),接受者會(huì)接收到發(fā)送的信號(hào)隊(duì)列中的信號(hào),而不是直接收到一次。
但是,信號(hào)不能無(wú)限的排隊(duì),信號(hào)排隊(duì)的最大值受到SIGQUEUE_MAX
的限制,達(dá)到最大限制后,sigqueue 會(huì)失敗,errno 會(huì)被設(shè)置為 EAGAIN。
那么我們來(lái)嘗試一下,發(fā)送一個(gè)攜帶有額外數(shù)據(jù)的信號(hào)吧。 Show me the code??! 接收端
#include#include#include //void (*sa_sigaction)(int, siginfo_t *, void *); void handler(int signum, siginfo_t * info, void * context) { if(signum == SIGIO) printf("SIGIO signal: %d\n", signum); else if(signum == SIGUSR1) printf("SIGUSR1 signal: %d\n", signum); else printf("error\n"); if(context) { printf("content: %d\n", info->si_int); printf("content: %d\n", info->si_value.sival_int); } } int main(void) { //int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); struct sigaction act; /* struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; }; */ act.sa_sigaction = handler; act.sa_flags = SA_SIGINFO; sigaction(SIGIO, &act, NULL); sigaction(SIGUSR1, &act, NULL); for(;;) { sleep(10000); } return 0; }
發(fā)送端
#include #include #include#include int main(int argc, char** argv) { if(4 != argc) { printf("[Arguments ERROR!]\n"); printf("\tUsage:\n"); printf("\t\t%s \n", argv[0]); return -1; } int pid = atoi(argv[1]); int sig = atoi(argv[2]); if(pid > 0 && sig > 0) { //int sigqueue(pid_t pid, int sig, const union sigval value); union sigval val; val.sival_int = atoi(argv[3]); printf("send: %d\n", atoi(argv[3])); sigqueue(pid, sig, val); } else { printf("Target_PID or Signal_Number MUST bigger than 0!\n"); } return 0; }
接收到的信號(hào)和信息
發(fā)送的信號(hào)和數(shù)據(jù)
關(guān)于“Linux的Signal機(jī)制是什么”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對(duì)“Linux的Signal機(jī)制是什么”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。