日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
深入探索LinuxSignal.h信號(hào)處理機(jī)制(linuxsignal.h)

在Linux系統(tǒng)中,信號(hào)(signal)是一種異步事件的機(jī)制,可以用來(lái)通知進(jìn)程發(fā)生了某種事件。Linux系統(tǒng)提供了Signal.h頭文件來(lái)支持信號(hào)處理機(jī)制,其中包含了各種信號(hào)相關(guān)的常量、結(jié)構(gòu)體和函數(shù)。

我們擁有10余年網(wǎng)頁(yè)設(shè)計(jì)和網(wǎng)站建設(shè)經(jīng)驗(yàn),從網(wǎng)站策劃到網(wǎng)站制作,我們的網(wǎng)頁(yè)設(shè)計(jì)師為您提供的解決方案。為企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)、微信開(kāi)發(fā)、小程序設(shè)計(jì)、手機(jī)網(wǎng)站制作設(shè)計(jì)HTML5、等業(yè)務(wù)。無(wú)論您有什么樣的網(wǎng)站設(shè)計(jì)或者設(shè)計(jì)方案要求,我們都將富于創(chuàng)造性的提供專業(yè)設(shè)計(jì)服務(wù)并滿足您的需求。

本文將從以下幾個(gè)方面,包括信號(hào)的基本概念、信號(hào)的分類、信號(hào)的發(fā)送和接收、信號(hào)的處理方式以及信號(hào)的應(yīng)用實(shí)例。

一、信號(hào)的基本概念

信號(hào)是由操作系統(tǒng)發(fā)送給進(jìn)程的一種通知機(jī)制,用于向進(jìn)程發(fā)送各種事件的通知。當(dāng)某個(gè)事件發(fā)生時(shí),操作系統(tǒng)會(huì)向特定的進(jìn)程發(fā)送相應(yīng)的信號(hào),進(jìn)程可以注冊(cè)信號(hào)處理函數(shù)來(lái)處理這些信號(hào)。

Linux系統(tǒng)中有幾十種不同的信號(hào),每一種信號(hào)都用一個(gè)整數(shù)常量來(lái)表示。這些常量定義在Signal.h頭文件中,并以”SIG”開(kāi)頭。例如,SIGINT表示當(dāng)用戶按下Ctrl+C時(shí)發(fā)送給前臺(tái)進(jìn)程的信號(hào),SIGTERM表示進(jìn)程終止信號(hào),SIGKILL表示無(wú)法處理或終止進(jìn)程的強(qiáng)制終止信號(hào)。

二、信號(hào)的分類

Linux系統(tǒng)中的信號(hào)可以根據(jù)不同的分類方式進(jìn)行分類,其中較為常見(jiàn)的分類方式包括以下幾種:

1.默認(rèn)信號(hào)和自定義信號(hào)

默認(rèn)信號(hào)是由系統(tǒng)定義的且不能被修改的信號(hào),如SIGTERM、SIGKILL等。自定義信號(hào)可以由用戶根據(jù)自己的需求來(lái)定義,如SIGUSR1、SIGUSR2等。

2.同步信號(hào)和異步信號(hào)

同步信號(hào)是進(jìn)程在執(zhí)行某些操作時(shí)自己產(chǎn)生的信號(hào),如除零錯(cuò)誤、訪問(wèn)非法地址等。異步信號(hào)是由進(jìn)程外部的事件(如按鍵、定時(shí)器、網(wǎng)絡(luò)套接字等)觸發(fā)引起的信號(hào)。

3.可靠信號(hào)和不可靠信號(hào)

可靠信號(hào)是指能保證信號(hào)不會(huì)被丟失或重復(fù)發(fā)送的信號(hào)。不可靠信號(hào)可能會(huì)在信號(hào)處理函數(shù)還未執(zhí)行完畢時(shí)再次被發(fā)送,或者在信號(hào)處理函數(shù)中多次發(fā)送。

三、信號(hào)的發(fā)送和接收

Linux系統(tǒng)中,進(jìn)程可以使用kill函數(shù)向其他進(jìn)程或自己發(fā)送信號(hào)。kill函數(shù)的原型如下:

“`c++

#include

int kill(pid_t pid, int sig);

“`

其中pid參數(shù)表示接收信號(hào)的進(jìn)程ID,sig參數(shù)表示發(fā)送的信號(hào)。

接收信號(hào)的進(jìn)程需要通過(guò)signal函數(shù)來(lái)注冊(cè)信號(hào)處理函數(shù),如:

“`c++

#include

void signal_handler(int sig) {

// 處理信號(hào)

}

int mn() {

signal(SIGINT, signal_handler); // 注冊(cè)鍵盤(pán)中斷信號(hào)處理函數(shù)

while (1) {

// 循環(huán)等待信號(hào)

}

return 0;

}

“`

在本例中,調(diào)用signal函數(shù)來(lái)注冊(cè)SIGINT信號(hào),并指定了signal_handler作為處理函數(shù)。當(dāng)接收到SIGINT信號(hào)時(shí),操作系統(tǒng)會(huì)調(diào)用signal_handler處理函數(shù)來(lái)處理信號(hào)。

四、信號(hào)的處理方式

接收到信號(hào)之后,操作系統(tǒng)會(huì)調(diào)用之前注冊(cè)的信號(hào)處理函數(shù)來(lái)處理信號(hào)。關(guān)于信號(hào)處理函數(shù)的基本要求如下:

1.信號(hào)處理函數(shù)必須是一個(gè)C語(yǔ)言函數(shù),返回值為void。

2.信號(hào)處理函數(shù)不能有任何參數(shù)。

3.信號(hào)處理函數(shù)必須是可重入的,因?yàn)樗赡茉谌魏螘r(shí)間被調(diào)用。

信號(hào)處理函數(shù)有以下三種處理方式:

1.默認(rèn)處理方式

默認(rèn)處理方式就是不做任何處理,直接忽略信號(hào)或終止進(jìn)程??梢允褂胹ignal函數(shù)進(jìn)行設(shè)置,如:

“`c++

#include

signal(SIGINT, SIG_DFL); // 默認(rèn)操作為終止進(jìn)程

“`

2.忽略信號(hào)

可以使用signal函數(shù)將信號(hào)處理函數(shù)設(shè)置為SIG_IGN來(lái)忽略某個(gè)信號(hào),如:

“`c++

#include

signal(SIGINT, SIG_IGN); // 忽略鍵盤(pán)中斷信號(hào)

“`

3.自定義處理方式

可以編寫(xiě)自定義的信號(hào)處理函數(shù)來(lái)處理特定的信號(hào),如:

“`c++

#include

void signal_handler(int sig) {

// 處理信號(hào)

}

signal(SIGINT, signal_handler); // 注冊(cè)鍵盤(pán)中斷信號(hào)處理函數(shù)

“`

五、信號(hào)的應(yīng)用實(shí)例

Linux系統(tǒng)中,信號(hào)機(jī)制廣泛應(yīng)用于進(jìn)程間的通信、進(jìn)程控制、時(shí)間管理等領(lǐng)域。下面列舉幾個(gè)信號(hào)的應(yīng)用實(shí)例。

1.進(jìn)程間通信

可以使用kill函數(shù)向其他進(jìn)程發(fā)送自定義信號(hào),如:

“`c++

kill(pid, SIGUSR1); // 向進(jìn)程pid發(fā)送SIGUSR1信號(hào)

“`

收到信號(hào)的進(jìn)程可以根據(jù)信號(hào)類型和來(lái)源,決定如何響應(yīng)。例如,可以使用自定義信號(hào)來(lái)實(shí)現(xiàn)雙方進(jìn)程的心跳檢測(cè)、資源分配等功能。

2.進(jìn)程控制

可以使用信號(hào)機(jī)制來(lái)控制進(jìn)程的行為,例如通過(guò)SIGSTOP和SIGCONT信號(hào)來(lái)停止和繼續(xù)進(jìn)程的執(zhí)行,如:

“`c++

kill(pid, SIGSTOP); // 停止進(jìn)程pid的執(zhí)行

kill(pid, SIGCONT); // 繼續(xù)進(jìn)程pid的執(zhí)行

“`

3.時(shí)間管理

可以使用定時(shí)器信號(hào)來(lái)進(jìn)行時(shí)間管理,例如使用SIGALRM信號(hào)來(lái)實(shí)現(xiàn)鬧鐘功能,如:

“`c++

#include

#include

void alarm_handler(int sig) {

// 播放音樂(lè)或執(zhí)行其他操作

}

signal(SIGALRM, alarm_handler); // 注冊(cè)定時(shí)器信號(hào)處理函數(shù)

alarm(10); // 10秒后發(fā)送SIGALRM信號(hào)

pause(); // 等待定時(shí)器信號(hào)

“`

在本例中,使用alarm函數(shù)設(shè)置10秒鐘的定時(shí)器,當(dāng)定時(shí)器到期時(shí),將發(fā)送SIGALRM信號(hào)通知進(jìn)程。進(jìn)程在收到SIGALRM信號(hào)時(shí),調(diào)用alarm_handler函數(shù)進(jìn)行處理。

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來(lái)專注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),響應(yīng)式網(wǎng)站制作,設(shè)計(jì)師量身打造品牌風(fēng)格,熱線:028-86922220

當(dāng)linux應(yīng)用程序中存在多個(gè)異步通知時(shí)怎樣處理

驅(qū)動(dòng)程序運(yùn)行在內(nèi)核空間中,應(yīng)用程序運(yùn)行在用戶空間中,兩者是不能直接通信的。但在實(shí)際應(yīng)用中,在設(shè)備已經(jīng)準(zhǔn)備好的時(shí)候,我們希望通知用戶程序搏告坦設(shè)備已經(jīng)ok,用戶程序可以讀取了,這樣應(yīng)用程序就不需要一直查詢?cè)撛O(shè)備的狀態(tài),從而節(jié)約了資源,這就是異步通知。好,那下一個(gè)問(wèn)題就來(lái)了,這個(gè)過(guò)程如何實(shí)現(xiàn)呢?簡(jiǎn)單,兩方面的工作。

一 驅(qū)動(dòng)方面:

1. 在設(shè)備抽象的數(shù)據(jù)結(jié)構(gòu)中增加一個(gè)struct fasync_struct的指針

2. 實(shí)現(xiàn)設(shè)備操作中的fasync函數(shù),這個(gè)函數(shù)很簡(jiǎn)單,其主體就是調(diào)用內(nèi)核的fasync_helper函數(shù)。

3. 在需要向用戶空間通知的地方(例如中斷中)調(diào)用內(nèi)核的kill_fasync函數(shù)。

4. 在驅(qū)動(dòng)的release方法中調(diào)用前面定義的fasync函數(shù)

呵呵,簡(jiǎn)單吧,就三點(diǎn)。其中fasync_helper和kill_fasync都是內(nèi)核函數(shù),我們只需要調(diào)用就可以了。在

1中定義的指針是一個(gè)重要參數(shù),fasync_helper和kill_fasync會(huì)使用這個(gè)參數(shù)。

二 應(yīng)用層方面

1. 利用signal或者sigaction設(shè)置SIGIO信號(hào)的處理函數(shù)

2. fcntl的F_SETOWN指令設(shè)置當(dāng)前進(jìn)程為設(shè)備文件owner

3. fcntl的F_SETFL指令設(shè)置FASYNC標(biāo)志

完成了以上的工作的話,當(dāng)內(nèi)核執(zhí)行到kill_fasync函數(shù),用戶空間SIGIO函數(shù)的處理函數(shù)就會(huì)被調(diào)用了。

呵呵,看起來(lái)不是很復(fù)雜把,讓我們結(jié)合具體代碼看看就更明白了。

先從應(yīng)用層代碼開(kāi)始吧:

#include

#include

#include

#include

#include

#include

#define MAX_LEN 100

//處理函數(shù),沒(méi)什么好講的,用戶自己定義

void input_handler(int num)

{

char data;

int len;

//讀取并輸出STDIN_FILENO上的輸入

len = read(STDIN_FILENO, &data, MAX_LEN);

data = 0;

printf(“input available:%s\n”, data);

}

void main()

{

int oflags;

//啟動(dòng)信號(hào)驅(qū)動(dòng)機(jī)制,將SIGIO信號(hào)同input_handler函數(shù)關(guān)聯(lián)起來(lái),一旦產(chǎn)生SIGIO信號(hào),就會(huì)執(zhí)行input_handler

signal(SIGIO, input_handler);

//STDIN_FILENO是打開(kāi)的設(shè)備文件描述符,F_SETOWN用來(lái)決定操作是干什么的,getpid()是個(gè)系統(tǒng)調(diào)用,

//功能是返回當(dāng)前進(jìn)程的進(jìn)程號(hào),整個(gè)函數(shù)基桐的功能是STDIN_FILENO設(shè)置這個(gè)設(shè)備文件的擁有者為當(dāng)前進(jìn)程。

fcntl(STDIN_FILENO, F_SETOWN, getpid());

//得到打開(kāi)文件描述符的狀態(tài)

oflags = fcntl(STDIN_FILENO, F_GETFL);

//設(shè)置文件描述符的狀態(tài)為oflags | FASYNC屬性,一旦文件描述符被設(shè)置成具有FASYNC屬性的狀態(tài),

//也就是將設(shè)備文件切換到異步操作模式。這時(shí)系統(tǒng)就會(huì)自動(dòng)調(diào)用驅(qū)動(dòng)程序的fasync方法。

fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

//最后進(jìn)入一個(gè)死循環(huán),程序什么都不干了,只有信號(hào)能激發(fā)input_handler的運(yùn)行

/友凱/如果程序中沒(méi)有這個(gè)死循環(huán),會(huì)立即執(zhí)行完畢

while (1);

}

再看驅(qū)動(dòng)層代碼,驅(qū)動(dòng)層其他部分代碼不變,就是增加了一個(gè)fasync方法的實(shí)現(xiàn)以及一些改動(dòng)

//首先是定義一個(gè)結(jié)構(gòu)體,其實(shí)這個(gè)結(jié)構(gòu)體存放的是一個(gè)列表,這個(gè)

//列表保存的是一系列設(shè)備文件,SIGIO信號(hào)就發(fā)送到這些設(shè)備上

static struct fasync_struct *fasync_queue;

//fasync方法的實(shí)現(xiàn)

static int my_fasync(int fd, struct file * filp, int on)

{

int retval;

//將該設(shè)備登記到fasync_queue隊(duì)列中去

retval=fasync_helper(fd,filp,on,&fasync_queue);

if(retval

{

return retval;

}

return 0;

}

在驅(qū)動(dòng)的release方法中我們?cè)僬{(diào)用my_fasync方法

int my_release(struct inode *inode, struct file *filp)

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..

}

這樣后我們?cè)谛枰牡胤剑ū热缰袛啵┱{(diào)用下面的代碼,就會(huì)向fasync_queue隊(duì)列里的設(shè)備發(fā)送SIGIO信號(hào)

,應(yīng)用程序收到信號(hào),執(zhí)行處理程序

if (fasync_queue)

kill_fasync(&fasync_queue, SIGIO, POLL_IN);

好了,這下大家知道該怎么用異步通知機(jī)制了吧?

以下是幾點(diǎn)說(shuō)明:

1 兩個(gè)函數(shù)的原型

int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);

一個(gè)”幫忙者”, 來(lái)實(shí)現(xiàn) fasync 設(shè)備方法. mode 參數(shù)是傳遞給方法的相同的值, 而 fa 指針指向一個(gè)設(shè)

備特定的 fasync_struct *

void kill_fasync(struct fasync_struct *fa, int sig, int band);

如果這個(gè)驅(qū)動(dòng)支持異步通知, 這個(gè)函數(shù)可用來(lái)發(fā)送一個(gè)信號(hào)到登記在 fa 中的進(jìn)程.

2.

fasync_helper 用來(lái)向等待異步信號(hào)的設(shè)備鏈表中添加或者刪除設(shè)備文件, kill_fasync被用來(lái)通知擁有相關(guān)設(shè)備的進(jìn)程. 它的參數(shù)是被傳遞的信號(hào)(常常是 SIGIO)和 band, 這幾乎都是 POLL_IN(但是這可用來(lái)發(fā)送”緊急”或者帶外數(shù)據(jù), 在網(wǎng)絡(luò)代碼里).

寫(xiě)一個(gè)linux下寫(xiě)個(gè)關(guān)于c語(yǔ)言的雙守護(hù)進(jìn)程,就是監(jiān)視一個(gè)進(jìn)程,當(dāng)其死掉,馬上將其重啟

這判州宴跟execvp函數(shù)的實(shí)現(xiàn)方式有關(guān):

int execvp(const char *file ,char * const argv );

execvp()會(huì)從PATH 環(huán)境變量所指的目錄中查找符掘銀合參數(shù)file的文件名,找到后便執(zhí)行該文件,然后將第二個(gè)參數(shù)argv傳給該欲執(zhí)行的文件。如果執(zhí)行成功則函數(shù)不會(huì)返回,執(zhí)行失敗則直接返回-1,失敗原因存于errno中。

之所以顯示“fail to exec”,是因?yàn)樵赑ATH環(huán)境變量所指的目錄中沒(méi)有名為“hello”的程序。建議進(jìn)行如下操作:

1、運(yùn)行“echo $PATH”,查看一跡亂下PATH環(huán)境變量指向那些目錄

2、編寫(xiě)一個(gè)輸出“hello world”的程序,并命名為hello,即執(zhí)行命令:

gcc -o hello hello.c

3、把名為”hello“的程序拷貝到PATH變量所指的其中一個(gè)目錄中

可以分三步來(lái)做:

做兩個(gè)簡(jiǎn)單的守護(hù)進(jìn)程,并能正常運(yùn)行

監(jiān)控進(jìn)程是否在運(yùn)行

啟動(dòng)進(jìn)程

綜合起來(lái)就可以了,代碼如下:

被監(jiān)控進(jìn)程thisisatest.c(來(lái)自

):

#include

#include

#include

#include

#include

#include

#include

#include

void init_daemon()

{

int pid;

int i;

pid=fork();

if(pid0) //父進(jìn)程退出

    exit(0);

 

setsid(); //使子進(jìn)程成為組長(zhǎng)

pid=fork();

if(pid>0)

    exit(0); //再次退出,使進(jìn)程不是組長(zhǎng),這樣進(jìn)程就不會(huì)打開(kāi)控制終端

else if(pid=0)

{

time(&t);

豎族     fprintf(fp,”current time is:%s\n”,asctime(localtime(&t)));  //轉(zhuǎn)換為本地時(shí)間輸出

fclose(fp);

}

    }

    return;

}

監(jiān)控進(jìn)程monitor.c:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define BUFSZ 150

void init_daemon()

{

int pid;

int i;

pid=fork();

if(pid0) //父進(jìn)程退出

    exit(0);

setsid(); //使子進(jìn)程成為組長(zhǎng)

pid=fork();

if(pid>0)

    exit(0); //再次退出,使進(jìn)程不是組長(zhǎng),這樣進(jìn)程就不會(huì)打開(kāi)控制終端

else if(pid=0)

{

count = does_service_work();

time(&t);

if(count>0)

  fprintf(fp,”current time is:%s and the process exists, the count is %d\n”,asctime(localtime(&t)), count);  //轉(zhuǎn)換為本地時(shí)間輸出

else

{

  fprintf(fp,”current time is:%s and the process does not exist, restart it!\n”,asctime(localtime(&t)));  //轉(zhuǎn)換為本地時(shí)間輸出

  system(“/home/user/daemon/thisisatest”); //啟動(dòng)服務(wù)

}

fclose(fp);

}

    }

    return;

}

具體CMD命令:

cc thisisatest.c -o thisisatest

./thisisatest

cc monitor.c -o monitor

./monitor

tail -f testfork3.log   — 查看日志

linux signal.h的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux signal.h,深入探索Linux Signal.h信號(hào)處理機(jī)制,當(dāng)linux應(yīng)用程序中存在多個(gè)異步通知時(shí)怎樣處理,寫(xiě)一個(gè)linux下寫(xiě)個(gè)關(guān)于c語(yǔ)言的雙守護(hù)進(jìn)程,就是監(jiān)視一個(gè)進(jìn)程,當(dāng)其死掉,馬上將其重啟的信息別忘了在本站進(jìn)行查找喔。

成都創(chuàng)新互聯(lián)科技公司主營(yíng):網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、小程序制作、成都軟件開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)、微信開(kāi)發(fā)、成都小程序開(kāi)發(fā)、網(wǎng)站制作、網(wǎng)站開(kāi)發(fā)等業(yè)務(wù),是專業(yè)的成都做小程序公司、成都網(wǎng)站建設(shè)公司成都做網(wǎng)站的公司。創(chuàng)新互聯(lián)公司集小程序制作創(chuàng)意,網(wǎng)站制作策劃,畫(huà)冊(cè)、網(wǎng)頁(yè)、VI設(shè)計(jì),網(wǎng)站、軟件、微信、小程序開(kāi)發(fā)于一體。


當(dāng)前文章:深入探索LinuxSignal.h信號(hào)處理機(jī)制(linuxsignal.h)
轉(zhuǎn)載源于:http://m.5511xx.com/article/cddesij.html