第七講 為用戶編程終端控制和_第1頁(yè)
第七講 為用戶編程終端控制和_第2頁(yè)
第七講 為用戶編程終端控制和_第3頁(yè)
第七講 為用戶編程終端控制和_第4頁(yè)
第七講 為用戶編程終端控制和_第5頁(yè)
已閱讀5頁(yè),還剩69頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第七講為用戶編程終端控制和第1頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月主要內(nèi)容軟件工具與用戶程序讀取和修改終端驅(qū)動(dòng)程序的設(shè)置非阻塞輸入用戶輸入的超時(shí)信號(hào)fcntl及signal系統(tǒng)調(diào)用第2頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月與終端有關(guān)的程序用戶常用的程序例如vi、emacs及許多游戲程序經(jīng)常要有終端進(jìn)行交互它們?cè)O(shè)置終端驅(qū)動(dòng)程序的擊鍵和輸出處理方式用戶經(jīng)常用到的幾種用戶終端設(shè)置:立即響應(yīng)擊鍵事件有限的輸入集輸入的超時(shí)屏蔽Ctrl-C第3頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月終端驅(qū)動(dòng)程序的模式/*rotate.c*/#include<stdio.h>#include<ctype.h>intmain(){intc;while((c=getchar())!=EOF){if(c==‘z’)c=‘a(chǎn)’elseif(islower(c))c++;putchar(c);}第4頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月規(guī)范模式:緩沖和編輯使用默認(rèn)設(shè)置運(yùn)行該程序(<-退格鍵)$gccrotate.c-orotate$./rotateabx<-cdbcdeefg^C$第5頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月輸入的內(nèi)容及程序所得到的內(nèi)容

rotate程序終端驅(qū)動(dòng)程序顯示器及鍵盤第6頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月標(biāo)準(zhǔn)輸入處理的特征程序未得到輸入的x,因?yàn)閯h除了它擊鍵的同時(shí)字符顯示在屏幕上,但直到按了回車,程序才接收到輸入^C鍵結(jié)束輸入并終止程序程序rotate并不負(fù)責(zé)這些事情,對(duì)于輸入的緩沖、回顯、編輯和控制鍵處理都由驅(qū)動(dòng)程序完成標(biāo)準(zhǔn)輸入處理的這些特征被啟動(dòng)時(shí),將終端連接稱為規(guī)范模式第7頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月非規(guī)范處理$stty-icanon;./rotateabbcxy^?cddeeffggh$sttyicanonstty-icanon命令關(guān)閉驅(qū)動(dòng)程序中的規(guī)范模式處理非規(guī)范模式?jīng)]有緩沖,輸入字母’a’,驅(qū)動(dòng)程序跳過(guò)緩沖層,字符直接送到程序,然后程序顯示字符’b’用戶輸入未緩沖可能會(huì)帶來(lái)麻煩,如果用戶想修改輸入時(shí),此時(shí)將無(wú)法修改第8頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月終端模式小結(jié)--規(guī)范模式

是用戶常見的模式輸入的字符保存在緩沖區(qū)接收到回車鍵時(shí)才將其中內(nèi)容發(fā)送到程序緩沖功能使驅(qū)動(dòng)程序可實(shí)現(xiàn)編輯功能,例如刪除字符、單詞或者行可通過(guò)命令stty或者系統(tǒng)調(diào)用tcsetattr修改執(zhí)行上述操作的特定鍵第9頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月終端模式小結(jié)--非規(guī)范模式

緩沖和編輯功能被關(guān)閉時(shí),連接被稱為處于非規(guī)范模式設(shè)備驅(qū)動(dòng)器仍然進(jìn)行特定字符的處理,例如Ctrl-C及換行符及回車符之間的轉(zhuǎn)換刪除單詞、字符及終止編輯鍵將不具有特殊含義而是被視作常規(guī)的數(shù)據(jù)輸入第10頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月終端模式小結(jié)--raw模式

每個(gè)處理步驟都被一個(gè)獨(dú)立的位控制,例如ISIG位控制Ctrl-C是否用于終止一個(gè)程序程序可隨意關(guān)閉所有這些處理步驟當(dāng)所有處理都被關(guān)閉后,驅(qū)動(dòng)程序?qū)⑤斎胫苯觽鬟f給程序。這種模式就稱為raw模式sttyraw命令第11頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月編寫一個(gè)用戶程序:play_again.cplay_again.c的邏輯:對(duì)用戶顯示提示問(wèn)題接受輸入如果是y返回0如果是n返回1第一個(gè)play_again0.c程序第12頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月play_again0.c的不足必須先按回車,程序才能接受到數(shù)據(jù)當(dāng)用戶按回車鍵時(shí),程序接收整行的數(shù)據(jù)對(duì)其進(jìn)行處理,例如Doyouwantanothertransaction(y/n)?surethingsurething第13頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月改進(jìn)方法首先關(guān)閉規(guī)范輸入,使得程序能夠在用戶敲鍵的同時(shí)得到輸入的字符set_crmode(){structtermiosttystate;tcgetattr(0,&ttystate); /*readcurr.setting */ttystate.c_lflag&=~ICANON; /*nobuffering */ttystate.c_cc[VMIN]=1; /*get1charatatime */tcsetattr(0,TCSANOW,&ttystate); /*installsettings */}第14頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月tty_mode(inthow)staticstructtermiosoriginal_mode;if(how==0) tcgetattr(0,&original_mode);elsereturntcsetattr(0,TCSANOW,&original_mode);第15頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月程序的主要過(guò)程首先調(diào)用tty_mode(0)函數(shù)保存當(dāng)前終端的設(shè)置信息set_crmode()函數(shù)首先將終端置于一個(gè)字符接一個(gè)字符的模式然后調(diào)用函數(shù)顯示一個(gè)提示符,并獲得一個(gè)響應(yīng)最后調(diào)用tty_mode(1)函數(shù)還原終端的設(shè)置第16頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月將終端置入字符輸入模式包括兩部分工作:將ICANON位關(guān)閉將控制字符數(shù)組中的VMIN下標(biāo)元素置一,VMIN的值告訴驅(qū)動(dòng)程序一次可以讀取多少個(gè)字符第17頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月編譯執(zhí)行play_again1程序此時(shí),程序可以直接接收和處理字符而不用等待回車鍵但對(duì)每個(gè)非法字符都提示錯(cuò)誤信息,可能比較煩可關(guān)閉回顯模式,丟掉不需要的字符,直到得到可接收的字符為止在set_crmode函數(shù)中加入語(yǔ)句ttystate.c_lflag&=~ECHO;第18頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月阻塞與非阻塞輸入當(dāng)調(diào)用getchar或者read等函數(shù)從文件描述符讀數(shù)據(jù)時(shí),這些調(diào)用一直等待用戶的輸入,如果用戶不輸入,則繼續(xù)等待,這種行為就術(shù)語(yǔ)阻塞輸入阻塞不僅僅是終端連接的屬性,而且是任何一個(gè)打開文件的屬性可使用fcntl或者open,通過(guò)開啟O_NDELAY標(biāo)志為文件描述符啟動(dòng)非阻塞輸入。第19頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月非阻塞讀取文件關(guān)閉文件描述符的阻塞狀態(tài),然后從中read時(shí),結(jié)果如何呢?如果能夠獲得輸入,read返回輸入數(shù)據(jù)及字符個(gè)數(shù),如果沒有輸入字符,read返回0,就像遇到文件末尾一樣,有錯(cuò)誤,返回-1.每個(gè)文件都有一塊保存未讀取數(shù)據(jù)的地方,若文件描述符置了O_NDELAY并且該空間為空,則read返回0。第20頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月play_again3.cget_response(){int input;printf("%s(y/n)?",question); /*ask */fflush(stdout); /*forceoutput */while(1){ sleep(SLEEPTIME); /*waitabit */ input=tolower(get_ok_char()); /*getnextchr*/ if(input=='y') return0; if(input=='n') return1; if(maxtries--==0) /*outatime? */ return2; /*sayso */ BEEP; }}第21頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月實(shí)驗(yàn)結(jié)果在輸入后,程序會(huì)延時(shí)一會(huì)兒如果長(zhǎng)時(shí)間不輸入,程序也會(huì)退出第22頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月fflush(out)函數(shù)終端驅(qū)動(dòng)對(duì)于輸出也是一行行緩沖的直到它收到一個(gè)換行符或者程序試圖從終端讀取數(shù)據(jù)時(shí)才會(huì)進(jìn)行輸出而此時(shí)getchar被延遲讀入,因此通過(guò)該函數(shù)將提示信息輸出到屏幕上,否則用戶將看不到提示信息。第23頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月Ctrl-C執(zhí)行上述程序時(shí),如果輸入Ctrl-C則程序終止運(yùn)行,同時(shí),也終止了整個(gè)登錄會(huì)話原因是什么呢?第24頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月Ctrl-C設(shè)置O_NDELAY設(shè)置crmode顯示提示符等待用戶輸入用戶輸入恢復(fù)tty設(shè)置恢復(fù)fcntl標(biāo)志退出程序流程CtrlC進(jìn)程被終止進(jìn)程正常退出時(shí)流向第25頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月Ctrl-C程序接收到Ctrl-C后,會(huì)立即退出,此時(shí),無(wú)法執(zhí)行重置啟動(dòng)程序的代碼返回shell并從用戶獲得命令行時(shí),終端仍處于非阻塞模式。shell調(diào)用read獲取命令行,但是因?yàn)樘幱诜亲枞麪顟B(tài),read立即返回0.這時(shí)shell程序就退出原因總結(jié):程序結(jié)束時(shí),文件描述符處于一個(gè)錯(cuò)誤的狀態(tài)。第26頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)Ctrl-C中斷當(dāng)前運(yùn)行的程。這個(gè)中斷由內(nèi)核的信號(hào)機(jī)制產(chǎn)生Ctrl-C的過(guò)程:用戶輸入Ctrl-C驅(qū)動(dòng)程序收到字符匹配VINTR和ISIG的字符被開啟驅(qū)動(dòng)程序調(diào)用信號(hào)系統(tǒng)信號(hào)系統(tǒng)發(fā)送SIGINT到進(jìn)程進(jìn)程收到SIGINT進(jìn)程消亡第27頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月什么是信號(hào)信號(hào)是由單個(gè)詞組成的消息,例如紅綠燈所發(fā)出的信息Ctrl-C時(shí),內(nèi)核向當(dāng)前運(yùn)行的進(jìn)程發(fā)送中斷信號(hào)每個(gè)信號(hào)都有一個(gè)數(shù)字編碼。中斷信號(hào)編碼通常是2第28頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)的來(lái)源信號(hào)來(lái)自內(nèi)核生成信號(hào)的請(qǐng)求來(lái)自3個(gè)地方:用戶--通過(guò)輸入Ctrl-C、Ctrl-\等請(qǐng)求內(nèi)核產(chǎn)生信號(hào)內(nèi)核--進(jìn)程執(zhí)行出錯(cuò)時(shí),內(nèi)核向進(jìn)程發(fā)送一個(gè)信號(hào),例如非法段訪問(wèn)、浮點(diǎn)數(shù)溢出等,也可通知進(jìn)程特定事件的發(fā)生。進(jìn)程--通過(guò)系統(tǒng)調(diào)用kill給另一個(gè)進(jìn)程發(fā)送信號(hào)。進(jìn)程之間可通過(guò)信號(hào)通信第29頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月同步與異步信號(hào)由進(jìn)程的某個(gè)操作產(chǎn)生的信號(hào)稱為同步信號(hào),例如被零除用戶擊鍵這樣的進(jìn)程外的事件引起的信號(hào)稱為異步信號(hào)第30頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)列表信號(hào)編號(hào)及其名字可在/usr/include/signal.h文件中找到,例如SIGINT為中斷信號(hào),SIGQUIT退出信號(hào),SIGSEGV非法段訪問(wèn)信號(hào)可以使用信號(hào)消滅一個(gè)進(jìn)程,也有辦法保護(hù)自己不被殺死第31頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月進(jìn)程處理信號(hào)的方法進(jìn)程通過(guò)signal系統(tǒng)調(diào)用告訴內(nèi)核如何處理信號(hào)進(jìn)程有3個(gè)選擇:(1)接受默認(rèn)處理SIGINT默認(rèn)處理為消亡,進(jìn)程通過(guò)系統(tǒng)調(diào)用signal(SIGINT,SIG_DFL)恢復(fù)默認(rèn)處理(2)忽略信號(hào)signal(SIGINT,SIG_IGN)系統(tǒng)調(diào)用告訴內(nèi)核忽略該信號(hào)第32頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月進(jìn)程處理信號(hào)的方法(3)調(diào)用一個(gè)函數(shù),這是3種方法中最強(qiáng)大的一個(gè)。例如在play_again3程序中,當(dāng)用戶輸入Ctrl-C時(shí),程序收到信號(hào)后執(zhí)行一個(gè)恢復(fù)設(shè)置的函數(shù)就不會(huì)發(fā)生上述情況了程序能夠告訴內(nèi)核,當(dāng)信號(hào)來(lái)時(shí)調(diào)用哪個(gè)函數(shù),signal(SIGINT,function);信號(hào)到來(lái)時(shí)所調(diào)用的函數(shù)稱為信號(hào)處理函數(shù)第33頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月signal系統(tǒng)調(diào)用目標(biāo)簡(jiǎn)單的信號(hào)處理頭文件#include<signal.h>函數(shù)原型result=signal(intsignum,void(*action)(int));參數(shù)signum需響應(yīng)的信號(hào)action如何響應(yīng)返回值-1遇到錯(cuò)誤prevaction返回之前的處理函數(shù)指針第34頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月signal系統(tǒng)調(diào)用其中action可以是函數(shù)名也可以是如下兩種特殊值之一:SIG_IGN,忽略信號(hào)SIG_DFL將信號(hào)恢復(fù)為默認(rèn)處理signal返回前一個(gè)處理函數(shù)。值為指向該函數(shù)的指針第35頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)處理的例子sigdemo1.c

#include <stdio.h>#include <signal.h>main(){ void f(int); /*declarethehandler */ int i; signal(SIGINT,f); /*installthehandler */ for(i=0;i<5;i++){ /*dosomethingelse */ printf("hello\n"); sleep(1); }}voidf(intsignum) /*thisfunctioniscalled*/{ printf("OUCH!\n");}第36頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)處理過(guò)程main(){signal(SIGINT,f);for(i=0;i<5;i++){printf(“hello\n”);sleep(1);}}正??刂屏餍盘?hào)函數(shù)f(){printf(“OUCH”);}第37頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigdemo1.c執(zhí)行結(jié)果hellohellohellohello^COUCH!hello第38頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月忽略信號(hào)sigdemo2.c

#include <stdio.h>#include <signal.h>main(){ signal(SIGINT,SIG_IGN); printf("youcan'tstopme!\n"); while(1) { sleep(1); printf("haha\n"); }}第39頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigdemo2.c程序執(zhí)行結(jié)果youcan'tstopme!hahahaha^Chahahaha^Chahahaha^\退出第40頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigdemo2.c調(diào)用signal忽略中斷信號(hào),可以隨意按Ctrl-C而不會(huì)對(duì)程序產(chǎn)生影響signal(SIGINT,SIG_IGNT)第41頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月作業(yè)6.10第42頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月處理多個(gè)信號(hào)當(dāng)有多個(gè)信號(hào)到達(dá)進(jìn)程時(shí),該如何處理?第43頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月1.捕鼠器問(wèn)題

信號(hào)處理函數(shù)有點(diǎn)像捕鼠器早期版本中,在每次捕獲之后,都必須重設(shè)它們。例如voidhandler(ints){signal(SIGINT,handler);}第44頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月1.捕鼠器問(wèn)題即使設(shè)置的速度非??欤€是需要時(shí)間觸發(fā)處理函數(shù)及重新設(shè)置完成之前,有新的信號(hào)或者老鼠溜走這一脆弱的間隙使得原有的信號(hào)處理不可靠,因此稱為不可靠的信號(hào)第45頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月處理多個(gè)信號(hào)第二個(gè)信號(hào)打斷第一個(gè)信號(hào)的處理第二個(gè)信號(hào)被阻塞返回信號(hào)處理的地方是否要重新開始?信號(hào)的優(yōu)先級(jí)?第46頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月進(jìn)程的多個(gè)信號(hào)處理函數(shù)每次使用之后都要禁用嗎?如果SIGY消息在進(jìn)程處理SIGX消息時(shí)到達(dá)會(huì)發(fā)生什么?如果進(jìn)程還在處理前一個(gè)SIGX時(shí),第二個(gè)SIGX又到來(lái)會(huì)發(fā)生什么事情呢?第三個(gè)呢?如果信號(hào)到來(lái)時(shí),程序正在處理getchar或者read之類的輸入而阻塞,那會(huì)如何呢?第47頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月測(cè)試多個(gè)信號(hào)sigdemo3.c程序signal(SIGINT,inthandler); /*sethandler*/signal(SIGQUIT,quithandler); /*sethandler*/do{ printf("\nTypeamessage\n"); nchars=read(0,input,(INPUTLEN-1)); if(nchars==-1) perror("readreturnedanerror"); else{ input[nchars]='\0'; printf("Youtyped:%s",input); }}while(strncmp(input,"quit",4)!=0);}第48頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月voidinthandler(ints){ printf("Receivedsignal%d..waiting\n",s); sleep(2); printf("Leavinginthandler\n");}voidquithandler(ints){ printf("Receivedsignal%d..waiting\n",s); sleep(3); printf("Leavingquithandler\n");}第49頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月執(zhí)行結(jié)果Typeamessagehelloyoutyped:helloTypeamessage^\^CReceivedsignal3....Receivedsignal2....LeavinginthandlerLeavingquithandler第50頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月各種實(shí)驗(yàn)(1)輸入^C^C^C^C(2)^\^C^\^C(3)hello^CReturn(4)helloReturn^C(5)^\^\hello^C第51頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月第一種情況不可靠的信號(hào)若兩個(gè)SIGINT信號(hào)殺死了進(jìn)程,則系統(tǒng)是不可靠的信號(hào)若未殺死進(jìn)程,則處理函數(shù)在被調(diào)用后還有作用現(xiàn)代信號(hào)處理機(jī)制允許在兩者之間選擇默認(rèn)情況下,為后者第一次實(shí)驗(yàn)的結(jié)果為:信號(hào)函數(shù)執(zhí)行了兩次,后面的兩次函數(shù)丟失第52頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月第二種情況:SIGY打斷SIGX的處理

函數(shù)接連按下^C和^\時(shí)程序先跳到inthandler,然后跳到quithandler,然后再回到inthandler,最后回到主循環(huán)第二種情況的實(shí)驗(yàn):接收到^\后,程序進(jìn)入quithandler程序,接收到^C后,進(jìn)入inthandler程序,最后返回到quithandler程序說(shuō)明信號(hào)^C打斷信號(hào)^\第53頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月第三種情況:SIGX打斷SIGX的處理函數(shù)有三種可能:遞歸,調(diào)用同一個(gè)處理函數(shù)忽略第二個(gè)信號(hào)阻塞第二個(gè)信號(hào)直到第一個(gè)處理完畢第三種方法最好,第54頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月系統(tǒng)調(diào)用被中斷例如當(dāng)調(diào)用read或者getchar函數(shù)時(shí),程序接收到^C的信號(hào)然后程序執(zhí)行信號(hào)處理函數(shù),執(zhí)行完后,程序重新返回主循環(huán)程序是重新執(zhí)行read還是從read返回同時(shí)設(shè)置errno為EINTR呢?第55頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月實(shí)驗(yàn)結(jié)果:hello^CReturn時(shí),程序無(wú)法接收到hello輸入helloReturn^C時(shí),程序可接收到hellohel^CloReturn時(shí),程序只接收到lo^\^\hello^C時(shí),無(wú)法得到hello輸入,同時(shí)信號(hào)處理執(zhí)行完后,重新開始read第56頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月信號(hào)機(jī)制其他的弱點(diǎn)無(wú)法確定信號(hào)產(chǎn)生的原因---早期的模型只是告訴了信號(hào)的類型處理函數(shù)中無(wú)法安全阻塞其他消息voidinthandler(ints){intrv;void(*prev_qhandler)();prev_qhandler=signal(SIGQUIT,SIG_IGN);

….signal(SIGQUIT,prev_qhandler);}第57頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月無(wú)法同時(shí)調(diào)用inthandler以及忽略SIGQUIT無(wú)法阻塞SIGQUIT信號(hào)第58頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigaction可以處理多個(gè)信號(hào)目標(biāo)指定信號(hào)的處理函數(shù)頭文件#include<signal.h>函數(shù)原型result=signaction(intsignum,conststructsigaction*actionstructsigaction*prevaction));參數(shù)signum需處理的信號(hào)action指向描述操作的結(jié)構(gòu)的指針prevaction指向描述被替換操作的結(jié)構(gòu)指針?lè)祷刂?1遇到錯(cuò)誤0成功第59頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月定制信號(hào)處理structsigactionstructsigaction{void(*sa_handler)();void(*sa_sigaction)(int,siginfo_t*,void*);sigset_tsa_mask;intsa_flags;}其中sa_handler可以為SIG_DFL,SIG_IGN或者函數(shù)名稱,它是老的信號(hào)處理方式第60頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sa_sigaction為新的信號(hào)處理機(jī)制它可獲得信號(hào)編號(hào)及被調(diào)用的原因及產(chǎn)生問(wèn)題的上下文的相關(guān)信息使用舊的處理機(jī)制:structsigactionaction;action.sa_handler=handler_old;使用新的處理機(jī)制:structsigactionaction;action.sa_sigaction=handler_new;將sigaction中的標(biāo)志位sa_flags置為:SA_SIGINFO第61頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sa_flags標(biāo)志標(biāo)記含義SA_RESETHAND當(dāng)處理函數(shù)被調(diào)用時(shí)重置,即捕鼠器模式SA_NODEFER處理信號(hào)時(shí)關(guān)閉信號(hào)自動(dòng)阻塞,因此允許遞歸調(diào)用信號(hào)處理函數(shù)SA_RESTART當(dāng)系統(tǒng)調(diào)用是針對(duì)一些慢速的設(shè)備或類似的系統(tǒng)調(diào)用,重新開始而不是返回SA_SIGINFO指明使用sa_sigaction的處理函數(shù)值。如果它未設(shè)置,則使用舊處理機(jī)制,若設(shè)置,則傳給處理函數(shù)的包括信號(hào)編號(hào)、信號(hào)產(chǎn)生的原因和條件等信息第62頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigaction的例子 structsigactionnewhandler;/*newsettings*/ sigset_tblocked;/*setofblockedsigs*/ void inthandler();/*thehandler*/ char x[INPUTLEN]; /*loadthesetwomembersfirst*/ newhandler.sa_handler=inthandler;/*handlerfunction*/ newhandler.sa_flags=SA_RESETHAND|SA_RESTART;/*options*/ /*thenbuildthelistofblockedsignals*/ sigemptyset(&blocked);/*clearallbits*/ sigaddset(&blocked,SIGQUIT); /*addSIGQUITtolist*/ newhandler.sa_mask=blocked;/*storeblockmask*/ if(sigaction(SIGINT,&newhandler,NULL)==-1) perror("sigaction");第63頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月防止數(shù)據(jù)損毀臨界區(qū)修改一個(gè)數(shù)據(jù)結(jié)構(gòu)的代碼若在運(yùn)行時(shí)被打斷,將導(dǎo)致數(shù)據(jù)的不完整或損毀該代碼稱為臨界區(qū)臨界區(qū)不一定就在信號(hào)處理函數(shù)中保護(hù)它的最簡(jiǎn)單的辦法就是忽略或阻塞處理函數(shù)將要使用或修改特定數(shù)據(jù)的信號(hào)第64頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月阻塞信號(hào):sigprocmask和sigsetop

在信號(hào)處理一級(jí)或者進(jìn)程一級(jí)阻塞信號(hào)在處理一個(gè)信號(hào)時(shí)阻塞另一個(gè)信號(hào),設(shè)置structsigaction中的sa_mask成員位sa_mask指定哪些信號(hào)要被阻塞sa_mask類型為sigset_t,它定義了信號(hào)集合第65頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月進(jìn)程的阻塞信號(hào)任何時(shí)候進(jìn)程都有一些信號(hào)被阻塞,這個(gè)信號(hào)的集合被稱為信號(hào)擋板。系統(tǒng)調(diào)用sigprocmask可修改這個(gè)被阻塞的信號(hào)集sigprocmask是一個(gè)原子操作,根據(jù)所給的信號(hào)集來(lái)修改當(dāng)前被阻塞的信號(hào)集第66頁(yè),課件共74頁(yè),創(chuàng)作于2023年2月sigprocmask目標(biāo)修改當(dāng)前的信號(hào)擋板頭文件#include<signal.h>函數(shù)原型intresult=sigprocmask(inthow,constsigs

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論