日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

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

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

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

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

一、信號的基本概念

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

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

二、信號的分類

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

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

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

2.同步信號和異步信號

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

3.可靠信號和不可靠信號

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

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

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

“`c++

#include

int kill(pid_t pid, int sig);

“`

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

接收信號的進(jìn)程需要通過signal函數(shù)來注冊信號處理函數(shù),如:

“`c++

#include

void signal_handler(int sig) {

// 處理信號

}

int mn() {

signal(SIGINT, signal_handler); // 注冊鍵盤中斷信號處理函數(shù)

while (1) {

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

}

return 0;

}

“`

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

四、信號的處理方式

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

1.信號處理函數(shù)必須是一個C語言函數(shù),返回值為void。

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

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

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

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

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

“`c++

#include

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

“`

2.忽略信號

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

“`c++

#include

signal(SIGINT, SIG_IGN); // 忽略鍵盤中斷信號

“`

3.自定義處理方式

可以編寫自定義的信號處理函數(shù)來處理特定的信號,如:

“`c++

#include

void signal_handler(int sig) {

// 處理信號

}

signal(SIGINT, signal_handler); // 注冊鍵盤中斷信號處理函數(shù)

“`

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

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

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

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

“`c++

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

“`

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

2.進(jìn)程控制

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

“`c++

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

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

“`

3.時間管理

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

“`c++

#include

#include

void alarm_handler(int sig) {

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

}

signal(SIGALRM, alarm_handler); // 注冊定時器信號處理函數(shù)

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

pause(); // 等待定時器信號

“`

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

成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來專注數(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)用程序中存在多個異步通知時怎樣處理

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

一 驅(qū)動方面:

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

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

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

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

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

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

二 應(yīng)用層方面

1. 利用signal或者sigaction設(shè)置SIGIO信號的處理函數(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ù)就會被調(diào)用了。

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

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

#include

#include

#include

#include

#include

#include

#define MAX_LEN 100

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

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;

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

signal(SIGIO, input_handler);

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

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

fcntl(STDIN_FILENO, F_SETOWN, getpid());

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

oflags = fcntl(STDIN_FILENO, F_GETFL);

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

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

fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);

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

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

while (1);

}

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

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

//列表保存的是一系列設(shè)備文件,SIGIO信號就發(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ū)動的release方法中我們再調(diào)用my_fasync方法

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

{

//..processing..

drm_fasync(-1, filp, 0);

//..processing..

}

這樣后我們在需要的地方(比如中斷)調(diào)用下面的代碼,就會向fasync_queue隊(duì)列里的設(shè)備發(fā)送SIGIO信號

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

if (fasync_queue)

kill_fasync(&fasync_queue, SIGIO, POLL_IN);

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

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

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

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

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

備特定的 fasync_struct *

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

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

2.

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

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

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

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

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

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

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

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

gcc -o hello hello.c

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

可以分三步來做:

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

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

啟動進(jìn)程

綜合起來就可以了,代碼如下:

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

):

#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)程成為組長

pid=fork();

if(pid>0)

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

else if(pid=0)

{

time(&t);

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

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)程成為組長

pid=fork();

if(pid>0)

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

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)換為本地時間輸出

else

{

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

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

}

fclose(fp);

}

    }

    return;

}

具體CMD命令:

cc thisisatest.c -o thisisatest

./thisisatest

cc monitor.c -o monitor

./monitor

tail -f testfork3.log   — 查看日志

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

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


分享文章:深入探索LinuxSignal.h信號處理機(jī)制(linuxsignal.h)
分享URL:http://www.dlmjj.cn/article/cddesij.html