網(wǎng)站建設(shè)的基本規(guī)范有什么小時(shí)seo
?兩個(gè)進(jìn)程間想通訊,必須要通過(guò)內(nèi)核,今天講的信號(hào)其實(shí)本質(zhì)也是講進(jìn)程間通訊的意思,那么你為什么可以在shell環(huán)境下,可以和一個(gè)進(jìn)程發(fā)kill-9啊?
shell是不是相當(dāng)于一個(gè)進(jìn)程?你自己運(yùn)行的那個(gè)進(jìn)程是不是也相當(dāng)于一個(gè)進(jìn)程?這樣的話,是不是一個(gè)進(jìn)程給另外一個(gè)進(jìn)程發(fā)送信號(hào)啊?他本質(zhì)上也是進(jìn)程間通訊,也是需要通過(guò)內(nèi)核,
作業(yè),在父子進(jìn)程間執(zhí)行,psux的命令啊?
在兄弟進(jìn)程間,完成這么一個(gè)功能,同時(shí)增加別的功能
父進(jìn)程里面是不是需要回收啊?回收子進(jìn)程,
這個(gè)代碼你看一下你到底哪里沒(méi)寫出來(lái)
?
?
我們完成的功能是psux groupby里面的命令吧?
所以說(shuō)咱們應(yīng)該是在創(chuàng)建子進(jìn)程之前應(yīng)該創(chuàng)建一個(gè)管道啊?這樣的話,fork出這兩個(gè)子進(jìn)程以后呢?這兩個(gè)子進(jìn)程是不是都可以使用這兩個(gè)管道了啊?
實(shí)際上在使用管道的時(shí)候呢,是不是就使用了兩個(gè)文件描述符啊?我們操作管道是不是其實(shí)就是操作兩個(gè)文件描述符的?
在循環(huán)里面創(chuàng)建了兩個(gè)子進(jìn)程,在36為什么加break?
為了讓子進(jìn)程不再去fork子進(jìn)程,
循環(huán)創(chuàng)建兩個(gè)子進(jìn)程,
?
?
?
?
這個(gè)wpid>0 這個(gè)是不是表示子進(jìn)程已經(jīng)死掉了,至少死掉了一個(gè),至少你可以調(diào)用這個(gè)宏打印一下他的退出狀態(tài),65--71
父進(jìn)程做的事情就是這么些個(gè),這一塊咱們前面是不是寫過(guò)兩三次了?
第一個(gè)子進(jìn)程 i==0 79 我們的目的是讓他往管道里面寫吧?他執(zhí)行ps aux 這個(gè)命令 這一個(gè)和接下來(lái)的這一塊,是不是和咱們前面講的那個(gè)圖是一模一樣的?只不過(guò)是把那個(gè)父進(jìn)程變成子進(jìn)程吧?
所以說(shuō)他用哪端就留哪端,不用哪端就關(guān)閉哪端,在這他用的是管道的寫端,所以他關(guān)閉的是管道的讀端,
他執(zhí)行的dup2這個(gè)函數(shù) 是不是可以實(shí)現(xiàn)文件重定向啊?文件重定向和文件描述符的復(fù)制,本身上是不是一個(gè)意思啊?兩個(gè)說(shuō)法而已
那么他要將誰(shuí)重定向誰(shuí)?是不是應(yīng)該是把標(biāo)準(zhǔn)輸出重定向到管道的寫端啊?所以這一步操作就是干這一個(gè)事情的,這一步操作是不是前面咱們說(shuō)過(guò)兩三次了?還記的將標(biāo)準(zhǔn)輸出重定向到文件當(dāng)中去嗎?那個(gè)只不過(guò)fd[1]是一個(gè)open打開的一個(gè)文件啊?在這他是個(gè)管道 本質(zhì)上是不是一樣的啊?
在這執(zhí)行了一個(gè)命令 execlp這個(gè)命令 86,這個(gè)命令內(nèi)核當(dāng)中所做的操作是不是其實(shí)是將ps這個(gè)命令他的代碼端,是不是替換掉了,當(dāng)前這個(gè)子進(jìn)程的代碼段啊?如果說(shuō)這個(gè)函數(shù)執(zhí)行成功,后面perror這個(gè)函數(shù)還能執(zhí)行嗎 87 89?不能執(zhí)行了,其實(shí) 如果成功 后面這個(gè)相當(dāng)于廢話,冗余代碼 后面可以沒(méi)有,那是不是不用寫了?因?yàn)樗锌赡苁?#xff0c;那你比如說(shuō)你這個(gè)ps你寫錯(cuò)了,或者你的參數(shù)不對(duì),都有可能會(huì)報(bào)錯(cuò),出于習(xí)慣你把這個(gè)寫上 89
萬(wàn)一報(bào)錯(cuò)的話,你是不是可以看到啊?如果你不寫你就不知道了,
看第二個(gè)子進(jìn)程,i==1 第二個(gè)子進(jìn)程 很顯然是不是他要執(zhí)行管道右邊的group bash的命令啊?
所以說(shuō)在這呢也應(yīng)該是做重定向操作吧?當(dāng)然用哪端留哪端,不用哪端關(guān)哪端,在這他是不是用讀端?所以他關(guān)掉了寫端,接下來(lái)是不是和咱們前面講過(guò)的一模一樣了?
然后他也做了一個(gè)重定向,后面來(lái)執(zhí)行一個(gè)命令,這個(gè)execlp一定要會(huì)用100?
這個(gè)函數(shù)其實(shí)execlp還可以被這個(gè)execl函數(shù)代替啊?
如果你代替之后,那么你第一個(gè)參數(shù)是不是要加路徑了?怎么查看這個(gè)命令的路徑啊 which?
你這個(gè)用命令查的話,是不是只能查這個(gè)系統(tǒng)命令的這個(gè)路徑,你能查這個(gè)普通用戶寫的這個(gè)應(yīng)用程序的路徑嗎?查不了了,
這個(gè)代碼應(yīng)該說(shuō)有一定的綜合性,在這里咱們綜合用到了 創(chuàng)建管道, fork ?循環(huán)創(chuàng)建子進(jìn)程的時(shí)候需要你注意的事項(xiàng),
父進(jìn)程回收子進(jìn)程 waitpid waitpid 函數(shù)的使用,務(wù)必要搞清楚
還有這幾個(gè)狀態(tài)的宏65 71 這幾個(gè)狀態(tài)的宏你記不住,你就查,man ?waitpid?
文件重定向操作,在一個(gè)子進(jìn)程里面執(zhí)行另一個(gè)命令,另一個(gè)系統(tǒng)命令,或者是應(yīng)用程序的函數(shù),execl的函數(shù),
綜合應(yīng)用了這些東西,應(yīng)該是這個(gè)代碼應(yīng)該說(shuō)這個(gè)如果大家掌握了咱們前面講過(guò)的那個(gè)父子進(jìn)程間完成ps aux 這樣的一個(gè)命令的話呢,那么我想在兄弟之間完成也不難,而且咱們這個(gè)wpid是不是前面也學(xué)過(guò)了?如何讓父進(jìn)程回收子進(jìn)程?大致也會(huì)了,其實(shí)就是兩段代碼一組合就可以了?
看懂代碼之后,看看是否符合自己的需求,不符合的話,拿過(guò)來(lái)大概改一改,就可以用了,一般就這么用的,很少會(huì)讓你從零開始寫,即便是從零開始寫,我想的話,應(yīng)該是會(huì)有大概的模板,比如說(shuō)這個(gè)代碼和這個(gè)代碼類似,你照著他寫就可以了,一般這么來(lái)寫,如果說(shuō)研發(fā)一個(gè)產(chǎn)品的話,從零開始寫,那么周期會(huì)很長(zhǎng),
他能夠用現(xiàn)實(shí)的東西,比如說(shuō)庫(kù)函數(shù),現(xiàn)成的類等等,他就用現(xiàn)成的,
共享映射區(qū),他的實(shí)現(xiàn)原理,將文件內(nèi)容映射到共享映射區(qū),那么這樣的話,你再操作這塊內(nèi)存是不是就相當(dāng)于操作這個(gè)文件啊?那么我們這個(gè)共享映射區(qū)其實(shí)就是一共有兩個(gè)類,一個(gè)是MAP_SHARED 一個(gè)是MAP_PRIVATE那其中MAP_SHARED是不是能夠?qū)⑿薷膬?nèi)存的數(shù)據(jù)反應(yīng)到文件當(dāng)中去?但是MAP_PRIVATE就不行了,一般時(shí)候用的話,就用MAP_SHARED就可以了,
這個(gè)關(guān)于mmap函數(shù)的用法,咱們就不過(guò)多的說(shuō)了,那么這個(gè)函數(shù)呢,雖然說(shuō)參數(shù)比較多,但是很多參數(shù)都是有固定寫法的,那么唯一有那么一兩個(gè)讓你準(zhǔn)備的 是不是就那個(gè)文件描述符了?還有文件大小,其他的要你準(zhǔn)備嗎?都是現(xiàn)成的,直接填就可以了,mmap他不但能夠完成父子進(jìn)程間,或者兄弟進(jìn)程間,也就是有血緣關(guān)系的進(jìn)程間通訊,是不是也能夠完成沒(méi)有任何關(guān)系的兩個(gè)進(jìn)程間通訊啊?當(dāng)然你要想讓他完成任何兩個(gè)進(jìn)程通訊的話,必須有一個(gè)文件,
還有一個(gè)匿名映射,大家了解一下就可以了,匿名映射是不是只能運(yùn)用于有血緣關(guān)系的進(jìn)程間通訊啊?因?yàn)樗麤](méi)有文件,如果兩個(gè)毫不相干的進(jìn)程,他就沒(méi)有聯(lián)系的紐帶,
那么關(guān)于這個(gè)fifo 是不是更簡(jiǎn)單了?fifo是不是你得用一個(gè)文件啊?管道文件,這個(gè)管道文件是不是咱們操作系統(tǒng)里面的系統(tǒng)文件類型是一樣,第一個(gè)字母是p 那么這樣的話,必須是文件,那么兩個(gè)進(jìn)程通過(guò)打開一個(gè)共同的文件來(lái)操作這個(gè)管道,
基本上復(fù)習(xí)的文件就這么多
熟練使用信號(hào)捕捉函數(shù) sigaction 重點(diǎn)掌握
熟練使用信號(hào)捕捉函數(shù) sigrtal 這個(gè)不能跨平臺(tái)移植,只能在linux上使用,在其他系統(tǒng)中呢,他表現(xiàn)的行為有所區(qū)別,
sigaction都是一樣的,可移植的
你在linux寫這個(gè)用這個(gè),那么你拿到unixs上不做任何修改,也可以,但是用sigrtal這個(gè)的話就不一定了
熟練掌握使用信號(hào)完成子進(jìn)程的回收 ?是本章的重點(diǎn),
前面講回收,是不是父進(jìn)程在一個(gè)循環(huán)里面去循環(huán)回收啊?那么循環(huán)回收還能做其他的事情嗎?是不是做不了啊?這兒就可以了
也就是說(shuō)有子進(jìn)程
有子進(jìn)程退出,他才去回收,沒(méi)有子進(jìn)程退出他不管,有點(diǎn)類似于 你在網(wǎng)上買的貨,你是不是要在家等著貨過(guò)來(lái)呀,你不可能一會(huì)往那跑一趟 一會(huì)往那跑一趟去問(wèn)吧,人家打電話你去拿就可以了 最終是不是異步處理啊?,你并不知道你的貨什么時(shí)候到,對(duì)于這個(gè)來(lái)說(shuō),你并不知道你的子進(jìn)程什么時(shí)候死,
?
信號(hào)是信息的載體, 在c語(yǔ)言當(dāng)中,結(jié)構(gòu)體是不是也是信息的載體?
Linux/UNIX 環(huán)境下,古老、經(jīng)典的通信方式,這個(gè)信號(hào)已經(jīng)出了很長(zhǎng)時(shí)間了,他不是一個(gè)新的技術(shù),早就有了,現(xiàn)在依然是主要的通信手段
這個(gè)信號(hào)仍然是兩個(gè)進(jìn)程通信的主要手段之一
?
信號(hào)的優(yōu)先級(jí)高,
不管程序執(zhí)行了什么位置,只要是有信號(hào)發(fā)生了,優(yōu)先處理信號(hào),信號(hào)處理完以后呢,再回過(guò)頭來(lái)再執(zhí)行,剛才是從哪中斷的從哪執(zhí)行
信號(hào)是軟件層面的中斷,被稱為軟中斷
程序一開始運(yùn)行在用戶區(qū),運(yùn)行的時(shí)候有的時(shí)候需要接觸到內(nèi)核啊?下面是內(nèi)核區(qū),
進(jìn)程a要想給進(jìn)程b發(fā)送一個(gè)信號(hào),首先他其實(shí)進(jìn)程a是發(fā)給了內(nèi)核,然后由內(nèi)核再給你轉(zhuǎn)發(fā)給進(jìn)程B ?進(jìn)程a先發(fā)給內(nèi)核,然后內(nèi)核再轉(zhuǎn)給b 那么內(nèi)核怎么知道轉(zhuǎn)給b 你發(fā)信號(hào)的時(shí)候你kill 你會(huì)寫一個(gè) 當(dāng)然第一個(gè)肯定要寫一個(gè)哪個(gè)信號(hào)吧?要發(fā)哪個(gè)信號(hào) 給哪個(gè)進(jìn)程發(fā)哪個(gè)信號(hào),是不是至少兩個(gè)信息啊?一個(gè)是進(jìn)程pid 一個(gè)是進(jìn)程的編號(hào)吧,信號(hào)的編號(hào)?
所以說(shuō)你指定了進(jìn)程的pid了,那么這樣的話,其實(shí)是你先告訴內(nèi)核的吧?你這個(gè)進(jìn)程a kill的時(shí)候,你已經(jīng)告訴內(nèi)核了,你要給誰(shuí)發(fā)送信號(hào),那么內(nèi)核是不是就知道給誰(shuí)轉(zhuǎn)發(fā)了?所以說(shuō) 他知道轉(zhuǎn)給b 是不是返回來(lái)也是一樣的?把進(jìn)程b給進(jìn)程a是不是也是這樣的?
比如說(shuō)我這個(gè)里面,是我們這個(gè)方塊是我們的代碼,執(zhí)行到這個(gè)位置了,突然發(fā)生了信號(hào),他是不是優(yōu)先處理這個(gè)信號(hào)啊?這樣處理信號(hào),在這我們畫一個(gè),我們寫的處理信號(hào)的動(dòng)作是執(zhí)行一個(gè)函數(shù), 這個(gè)函數(shù)是我們自己寫的,用的是回調(diào)函數(shù),這個(gè)信號(hào)處理函數(shù), ?
也就是我們?cè)谔幚硇盘?hào)的意思
這個(gè)信號(hào)處理完了,回到哪去呢?從哪中斷回到哪。舉個(gè)例子 比如說(shuō)你這個(gè)信號(hào)執(zhí)行到第十行了,突然產(chǎn)生信號(hào)了,那么接下來(lái)是不是要處理這個(gè)信號(hào)呢?處理完這個(gè)信號(hào)接下來(lái)是不是又回到10行?從這個(gè)圖上我們可以看得出來(lái),信號(hào)的優(yōu)先級(jí) 要高于其他動(dòng)作啊
出現(xiàn)信號(hào)要優(yōu)先處理信號(hào),
處理完信號(hào)以后呢,再去執(zhí)行剛剛你從中斷的位置上,再繼續(xù)往下執(zhí)行,高于普通操作,信號(hào)有三種狀態(tài),一個(gè)是信號(hào)產(chǎn)生,這個(gè)信號(hào)是怎么產(chǎn)生的,這個(gè)信號(hào)是不是得產(chǎn)生啊?
你這個(gè)程序不close掉他會(huì)產(chǎn)生信號(hào)嗎?
sleep 100現(xiàn)在是不是已經(jīng)執(zhí)行起來(lái)了?
是不是你查的時(shí)候man 1 是不是你查的命令啊? 你不寫他從1開始發(fā)
man 2 查的是系統(tǒng)調(diào)用 或者是系統(tǒng)函數(shù)
man 3 查的是c語(yǔ)言的庫(kù)函數(shù)
man 7今天會(huì)講
定時(shí)器 alarm,每一個(gè)進(jìn)程都有一個(gè)唯一的定時(shí)器,這個(gè)定時(shí)器有點(diǎn)類似于手機(jī)上的鬧鐘,
非法訪問(wèn)內(nèi)存(段錯(cuò)誤)會(huì)close掉,
除0,你的進(jìn)程會(huì)立刻死掉
命令產(chǎn)生kill
未決:產(chǎn)生和遞達(dá)之間的狀態(tài)。主要由于阻塞(屏蔽)導(dǎo)致該狀態(tài)
一個(gè)進(jìn)程收到信號(hào),默認(rèn)會(huì)去處理它,但是如果這個(gè)信號(hào)被阻塞了,阻塞的意思是不是暫時(shí)不讓他處理的意思? 他就相當(dāng)于屏蔽掉他了,這時(shí)候就相當(dāng)于處于未決狀態(tài)
這個(gè)是后面講 信號(hào)級(jí)相關(guān)操作的時(shí)候會(huì)講這個(gè),
遞達(dá):遞送并且到達(dá)進(jìn)程。 信號(hào)已經(jīng)處理了 就是遞達(dá)狀態(tài)
?信號(hào)的處理方式 信號(hào)的處理動(dòng)作
有三個(gè)?
直接看手冊(cè)
man 7 signal 這個(gè)里面就能夠把這個(gè)信號(hào)相關(guān)的信息傳達(dá)出來(lái),比如說(shuō)signa1 dispositions 信號(hào)的處理方式,term是不是終止的意思?終止進(jìn)程
Ign 忽略信號(hào)
Core內(nèi)存非法訪問(wèn)照成的
stop進(jìn)程暫停
Cont 使進(jìn)程繼續(xù)執(zhí)行
stop 和Cont 他倆是一對(duì), 暫廳停止是一對(duì)
信號(hào)的四要素,每一個(gè)信號(hào) 用四種屬性去描述他
一個(gè)是信號(hào)的名字SIGHUP ?大寫的宏叫信號(hào)的名字,
SIGINT 是不是剛剛說(shuō)過(guò)了,ctrl+c 是不是可以產(chǎn)生這個(gè)信號(hào)啊?
value指的是信號(hào)的編號(hào)
action 信號(hào)的默認(rèn)處理動(dòng)作,什么叫默認(rèn)處理動(dòng)作啊? 那么對(duì)象如果你的進(jìn)程不處理他,他有一個(gè)默認(rèn)處理動(dòng)作
后面咱們會(huì)講怎么捕獲他,
comment 這個(gè)信號(hào)怎么產(chǎn)生的,一個(gè)信號(hào)描述,
被鍵盤中斷,其實(shí)就是說(shuō)的ctrl+c
SIGPIPE 往一個(gè)沒(méi)有讀端的管道寫數(shù)據(jù),你把他的管道讀端給關(guān)掉,然后你可以寫數(shù)據(jù),你看看會(huì)不會(huì)收到這個(gè)信號(hào),一定會(huì)收到這個(gè)信號(hào),
SIGCHLD重點(diǎn)講的這個(gè)信號(hào),Ign 忽略,什么情況下才會(huì)產(chǎn)生這個(gè)信號(hào)?是不是子進(jìn)程 停止或者終止
停止相當(dāng)于暫停的意思,stopped 和terminated是不一樣的,terminated是終止的意思,進(jìn)程徹底死掉了
The signals SIGKILL
and SIGSTOP cannot
caught,b1ocked, or ignored
不能阻塞 不能忽略,
收到這兩個(gè)信號(hào)SIGKILL ?SIGSTOP 必須有處理動(dòng)作,這兩個(gè)處理動(dòng)作一定是默認(rèn)動(dòng)作,不能定義,只能是默認(rèn)動(dòng)作吧?
SIGKILL的默認(rèn)動(dòng)作是什么呢?Kill signal默認(rèn)是終止的意思,Term
SIGSTOP stop 是暫停的意思
在這里面信號(hào)里面有3種值,
這個(gè)信號(hào)的編號(hào),有的是有三種值,SIGUSR1 SIGUSR2?
在一個(gè)系統(tǒng)上只有1個(gè)值,在linux系統(tǒng)下他是終端這個(gè)值,其中你不知道這個(gè)也沒(méi)有關(guān)系,因?yàn)槟阍谑褂眯盘?hào)的時(shí)候呢,你不要使用編號(hào),你使用宏名就可以了,那么宏名你管他是什么,不同的系統(tǒng)上他表現(xiàn)的數(shù)值不一樣,對(duì)于這個(gè)宏是不是都一樣的?
別的信號(hào)用的相對(duì)比較少,SIGIOT SIGEMT
SIGSTKFLT ... 你也不用再關(guān)注了 很少用它
其實(shí)信號(hào)的處理動(dòng)作還有兩個(gè),是暫停和繼續(xù)執(zhí)行,大部分都是終止,終止是不是才會(huì)對(duì)你的系統(tǒng)照成的影響最小啊? 你比如說(shuō)你這個(gè)你本來(lái)進(jìn)程被core掉了,你如果不知道怎么終止的話,他是不是會(huì)非法訪問(wèn)其他內(nèi)存啊?有可能給你修改吧?這一修改不得了,其他程序也會(huì)core掉了,是不是會(huì)照成連鎖反應(yīng)啊?
忽略 丟棄不處理的意思,相當(dāng)于就當(dāng)他沒(méi)發(fā)生
捕捉信號(hào) 捕捉是咱們需要注冊(cè)shell命令函數(shù),讓他去執(zhí)行我們自己定義的函數(shù),
信號(hào)有很強(qiáng)的延時(shí)性,信號(hào)處理是不是要進(jìn)入 內(nèi)核啊,我們信號(hào)是不是需要暫時(shí)的阻塞啊?那么阻塞 如果說(shuō)后面呢你不阻塞,再寫出注冊(cè),這個(gè)信號(hào)是能夠被處理的,從這點(diǎn)來(lái)說(shuō),我們可以知道,這個(gè)信號(hào)是有延時(shí)的,我們介紹信號(hào)集相關(guān)函數(shù),我給你介紹阻塞這一塊你就知道了,一開始你不處理他,后來(lái)呢,你又想處理他了,然后解除注冊(cè),這個(gè)信號(hào)就能夠被處理了,從這一點(diǎn)來(lái)說(shuō)也能夠感覺(jué)到這個(gè)信號(hào)是有延時(shí)性的
然后你去不阻塞他的話呢,他的這個(gè)延時(shí)你是感覺(jué)不到的,因?yàn)檫@個(gè)時(shí)間十分的短暫,這個(gè)信號(hào)處理的話呢,他會(huì)進(jìn)入到內(nèi)核,
咱們前面講到pcb的時(shí)候給大家說(shuō)過(guò)了,這個(gè)信號(hào)集相關(guān)的東西是不是都在這個(gè)pcb里面,在這里面主要指的是阻塞信號(hào)集和未決信號(hào)集。
?
信號(hào)相關(guān)的函數(shù), 先給大家講一個(gè),
signal函數(shù) 咱們用的比較多的,
完成一個(gè)信號(hào)的注冊(cè),注冊(cè)一個(gè)用戶自定義的函數(shù) 言外之意,這個(gè)信號(hào)是要發(fā)生的,就會(huì)去調(diào)用信號(hào)處理函數(shù),
是不是和
這個(gè)圖這個(gè)意思啊,這個(gè)代碼執(zhí)行到這個(gè)位置之后產(chǎn)生的信號(hào),是不是就會(huì)執(zhí)行信號(hào)處理函數(shù)啊?
這個(gè)函數(shù)是用戶自己寫的,用戶自己寫的函數(shù),還得調(diào)用signal函數(shù)完成注冊(cè),不然的話,人家怎么知道執(zhí)行哪個(gè)函數(shù)啊?
?typedef void (*sighandler t)(int);
sighandler_t signal(int signum,sighandler_t handler);
signum信號(hào)的編號(hào),每一個(gè)信號(hào)是不是都有一個(gè)編號(hào)啊?數(shù)字就是編號(hào),但是你使用的時(shí)候用哪個(gè)啊?用宏 不要用數(shù)字,sighandler_t ?第二個(gè)參數(shù)是信號(hào)處理函數(shù)的函數(shù)名 函數(shù)名代表函數(shù)的首地址,就是指針嘛 函數(shù)指針,那么這個(gè)函數(shù)指針,
指向這個(gè)函數(shù)呢,有一個(gè)參數(shù) int類型的,那么你說(shuō)這個(gè)int類型是個(gè)什么東西?
信號(hào)的編號(hào),
前面給大家講pipe 講管道的時(shí)候是不是給你說(shuō)
如果說(shuō)讀端全部關(guān)閉了,然后你再寫管道的話是不是會(huì)發(fā)生一個(gè),會(huì)產(chǎn)生信號(hào)啊?
創(chuàng)建了一個(gè)管道pipe 我關(guān)閉了寫端,
?
后面是讀吧?我把讀端給關(guān)閉 讓我寫,
0是讀端,我把讀端關(guān)閉了
調(diào)用signal注冊(cè)一個(gè)信號(hào)處理函數(shù),signal在哪調(diào)用都行,在關(guān)閉讀端前面調(diào)用也行,
第一個(gè)是信號(hào)編號(hào),第二個(gè)是信號(hào)處理函數(shù),我主要是想讓大家看一下,到底我把讀端關(guān)閉以后,然后我再寫入管道是不是會(huì)產(chǎn)生一個(gè)信號(hào),
接下來(lái)是不是你要寫這個(gè)sighandler函數(shù)了?
一個(gè)void 類型的
?他有一個(gè)參數(shù) signo,那么咱們打印一下 這個(gè)signo到底是不是這個(gè)sigpipe信號(hào),
?sigpipe 是13 打印這個(gè)signo是不是13就知道了吧?
產(chǎn)生了13信號(hào),這個(gè)信號(hào)是誰(shuí)產(chǎn)生的?內(nèi)核產(chǎn)生的信號(hào)發(fā)給當(dāng)前進(jìn)程 我把這個(gè)代碼原理再說(shuō)一下,
代碼很簡(jiǎn)單,調(diào)用pipe創(chuàng)建一個(gè)管道,創(chuàng)建管道,是不是在內(nèi)核就有一個(gè)緩沖區(qū)了?讀寫兩端來(lái)標(biāo)識(shí)這個(gè)緩沖區(qū),我們調(diào)用signal函數(shù),完成SIGPIPE信號(hào)的注冊(cè),第一個(gè)參數(shù)是信號(hào)的編號(hào),的個(gè)參數(shù)是信號(hào)的處理函數(shù), 也就是說(shuō)這個(gè)信號(hào)發(fā)生之后 去處理哪個(gè)函數(shù)的意思 去執(zhí)行哪個(gè)函數(shù),舉個(gè)例子,假如說(shuō)我這個(gè)函數(shù)執(zhí)行到 write這個(gè)位置了,他一寫 你如果寫完了 這個(gè)時(shí)候是不是信號(hào)產(chǎn)生了?
因?yàn)樗遣皇钦谕粋€(gè)沒(méi)有讀端的管道寫數(shù)據(jù)啊?內(nèi)核檢測(cè)到這個(gè)錯(cuò)誤了,立刻就產(chǎn)生了一個(gè)信號(hào),那么這個(gè)信號(hào)呢 產(chǎn)生信號(hào)是SIGPIPE信號(hào) 而且 我們這個(gè)當(dāng)前進(jìn)程是不是也注冊(cè)了這么一個(gè)信號(hào)啊?內(nèi)核就知道這個(gè)信號(hào)產(chǎn)生之后,去執(zhí)行這個(gè)sighandler函數(shù),sighandler函數(shù)是內(nèi)核執(zhí)行的還是你用戶進(jìn)程執(zhí)行的?是內(nèi)核執(zhí)行的,其實(shí)這個(gè)回調(diào)函數(shù),你想一下 回調(diào)函數(shù)一般是讓你自己寫這個(gè)函數(shù),讓別人去執(zhí)行,
回調(diào)函數(shù),實(shí)現(xiàn)是用戶進(jìn)行實(shí)現(xiàn)的,但是執(zhí)行,不是用戶進(jìn)行執(zhí)行的,對(duì)于這個(gè)sighandler函數(shù),是內(nèi)核執(zhí)行的這個(gè)函數(shù),那么內(nèi)核是怎么知道執(zhí)行這個(gè)函數(shù)了?因?yàn)槟阋呀?jīng)告訴他了28行,那么這個(gè)其實(shí)這個(gè)注冊(cè)呢 如果嚴(yán)格的說(shuō)是這樣說(shuō)
給內(nèi)核注冊(cè)一個(gè)信號(hào)處理函數(shù),是給內(nèi)核注冊(cè)的,那么內(nèi)核檢測(cè)到這個(gè)信號(hào)產(chǎn)生了是不是立刻就會(huì)執(zhí)行這個(gè)函數(shù)了? 它這個(gè)函數(shù)打印出來(lái)這個(gè)signo 13
這個(gè)是不是驗(yàn)證了咱們前面的說(shuō)法吧?
給一個(gè)沒(méi)有讀端的管道寫數(shù)據(jù),會(huì)產(chǎn)生signo信號(hào),是不是這樣的?
信號(hào)的特點(diǎn)是,必須在某種特定條件下才會(huì)產(chǎn)生,
信號(hào)的產(chǎn)生,信號(hào)比如說(shuō) 按鍵盤,命令 函數(shù) 軟中斷 硬件中斷 是不是都會(huì)產(chǎn)生信號(hào)啊?
信號(hào)的狀態(tài) 信號(hào)有3種狀態(tài),必達(dá)產(chǎn)生狀態(tài) 未結(jié)產(chǎn)生狀態(tài) 產(chǎn)生狀態(tài)
信號(hào)的四要素
每個(gè)信號(hào)多有編號(hào),
信號(hào)的名字,那個(gè)宏就是名字,我們用名字,不要用編號(hào)
信號(hào)的默認(rèn)處理動(dòng)作
大部分的信號(hào)的默認(rèn)處理動(dòng)作是終止?
因?yàn)橹挥羞@個(gè)進(jìn)程終止之后才會(huì)對(duì)系統(tǒng)產(chǎn)生的 ?( ?)最小,
信號(hào)是如何產(chǎn)生的,是不是后面兩個(gè)comment啊
action是不是默認(rèn)沖突 ?也就是說(shuō)這個(gè)comment是描述的這個(gè)信號(hào)是如何產(chǎn)生的,是不是前面咱們前面講的這個(gè)信號(hào)擴(kuò)展的時(shí)候說(shuō)過(guò)了,信號(hào)是在某種特定條件才會(huì)產(chǎn)生吧,這個(gè)信號(hào)雖然說(shuō)有這么多個(gè),但是對(duì)于我們來(lái)說(shuō) 有些信號(hào)需要我們了解一下,但是 這些信號(hào) 幾個(gè)常用到的信號(hào) 你大致了解了解,因?yàn)檫@些東西用的相對(duì)較多,你得知道,比如說(shuō)SIGINT 2號(hào)編號(hào)吧?是不是ctrl+c產(chǎn)生的?
SIGQUIT ctrl+z+/ 使進(jìn)程退出
SIGKtLL和 SIGSTOP.是不能被捕獲 阻塞忽略的,
SIGSEGV 這個(gè)信號(hào)呢,是非法訪問(wèn)內(nèi)存會(huì)產(chǎn)生的信號(hào)
端溢出,內(nèi)存溢出等等都會(huì)產(chǎn)生信號(hào)
SIGUSR1、SIGUSR2 這兩個(gè)信號(hào),是系統(tǒng)留給咱們自己來(lái)使用的,是用戶信號(hào),這兩個(gè)信號(hào) 我們自己可以來(lái)用,其他信號(hào)你不要亂發(fā),因?yàn)樗际窃谀撤N特定條件下產(chǎn)生的,但是你不能亂用,但是這兩個(gè)信號(hào) SIGUSR1、SIGUSR2 ?你自己隨便用
SIGALRM后面會(huì)講,會(huì)產(chǎn)生的信號(hào),
SIGTERM使進(jìn)程終止,
SIGTERM和SIGKILL有什么區(qū)別?都是使進(jìn)程終止,SIGKILL這個(gè)信號(hào)不能被捕獲,
SIGTERM能夠被捕獲但是,這個(gè)信號(hào)的默認(rèn)處理動(dòng)作是終止,那么如果說(shuō)你捕獲之后,你可以讓他不終止,
SIGCHLD重要的一個(gè)信號(hào),這個(gè)信號(hào)是子進(jìn)程退出之后,內(nèi)核會(huì)給它的父進(jìn)程發(fā)出一個(gè)信號(hào),那么他的父進(jìn)程收到之后,回收子進(jìn)程
這就是父進(jìn)程回收子進(jìn)程的一個(gè)時(shí)機(jī)
SIGSTOP使進(jìn)程暫停,
SIGCONT使進(jìn)程繼續(xù)執(zhí)行,
?
?
信號(hào)默認(rèn)處理動(dòng)作,信號(hào)默認(rèn)處理是5種,
信號(hào)注冊(cè),注冊(cè)由,信號(hào)產(chǎn)生之后,會(huì)執(zhí)行信號(hào)的注冊(cè)函數(shù),那個(gè)是一個(gè)回調(diào)函數(shù),那個(gè)函數(shù)實(shí)現(xiàn)是用戶實(shí)現(xiàn)的,調(diào)用是內(nèi)核調(diào)用的,
后面講信號(hào)的處理過(guò)程的時(shí)候,再說(shuō)
?
?
?
kill函數(shù),他對(duì)應(yīng)的系統(tǒng)命令是kill命令,
給指定進(jìn)程發(fā)送指定信號(hào),那么指定進(jìn)程是怎么標(biāo)識(shí)?是不是進(jìn)程的pid啊?發(fā)送指定信號(hào),那么這個(gè)信號(hào)怎么標(biāo)識(shí)啊?是不是信號(hào)編號(hào)啊?
所以說(shuō)你使用這個(gè)函數(shù)的時(shí)候,肯定是要有兩個(gè)參數(shù),第一個(gè)產(chǎn)生是編號(hào),第二個(gè)參數(shù)是進(jìn)程
kill命令在使用的時(shí)候是不是也是這樣kill -9
9是信號(hào)編號(hào),后面來(lái)個(gè)pid pid就是指的是進(jìn)程的pid 這就標(biāo)識(shí)了,給哪個(gè)進(jìn)程發(fā)送哪個(gè)信號(hào)
?
函數(shù)原型,int kill(pid_t pid, int sig)
pid_t這個(gè)變量的類型見(jiàn)沒(méi)見(jiàn)過(guò)?是不是進(jìn)程pid啊?進(jìn)程pid就是這個(gè)類型, 第二個(gè)是signo 信號(hào)的編號(hào)
成功返回0 ?失敗返回-1,
pid > 0:發(fā)送信號(hào)給指定的進(jìn)程。
pid =0: 發(fā)送信號(hào)給與調(diào)用 kill 函數(shù)進(jìn)程屬于同一進(jìn)程組的所有進(jìn)程。
舉例:父進(jìn)程循環(huán)創(chuàng)建3個(gè)子進(jìn)程,這三個(gè)子進(jìn)程和父進(jìn)程是不是同一組?如果說(shuō)你要想把這四個(gè)進(jìn)程一次性全部給殺死, 函數(shù)的pid 參數(shù)寫0,就可以了,那么這個(gè)0是什么意思呢?你要給這個(gè)當(dāng)前進(jìn)程,他自己,調(diào)用這個(gè)kill函數(shù)進(jìn)程 是不是叫單獨(dú)進(jìn)程啊?給他的一個(gè)組發(fā),發(fā)哪個(gè)信號(hào)都可以 ?發(fā)個(gè)-9就可以了
這樣的話一刪就可以把這4個(gè)進(jìn)程全部給他殺死,是不是相當(dāng)于殺了一個(gè)組啊?
pid < -1:取|pid|發(fā)給對(duì)應(yīng)進(jìn)程組。
如果pid< -1表示 取pid的絕對(duì)值發(fā)送給對(duì)應(yīng)進(jìn)程組,比如說(shuō)你這個(gè)進(jìn)程組,他的pid 他的組id是100,那么你這用的時(shí)候用多少?寫-100就可以了
那么寫-100表示給這個(gè)組發(fā)呢,這個(gè)東西殺傷面都比較大,一般不用
pid = -1=發(fā)送給進(jìn)程有權(quán)限發(fā)送的系統(tǒng)中所有進(jìn)程。
這個(gè)殺傷面更大,
如果你在root用戶里面調(diào)用這么一個(gè)函數(shù),
是不是其他的所有的用戶全部都受影響啊?因?yàn)閞oot用戶有最高權(quán)限,root用戶可以給普通用戶發(fā)送告急信號(hào),反過(guò)來(lái),普通用戶能不能給其他用戶 或者root用戶發(fā)送啊? 沒(méi)有權(quán)限,
這四個(gè)里面雖然說(shuō)了4個(gè),但是絕大多數(shù)情況下,99.9%的情況你只用第一個(gè),相對(duì)安全,假如說(shuō) 后面的這些參數(shù)你都不知道,你只知道>0的這么一個(gè)參數(shù),那么你能不能把這四個(gè)進(jìn)程全部殺死?來(lái)個(gè)循環(huán)就可以了
每個(gè)進(jìn)程都屬于一個(gè)進(jìn)程組,進(jìn)程組是一個(gè)或多個(gè)進(jìn)程集合,他們相互關(guān)聯(lián),共同完成一個(gè)實(shí)體任務(wù),每個(gè)進(jìn)程組都有一個(gè)進(jìn)程組長(zhǎng),默認(rèn)進(jìn)程組 ID 與進(jìn)程組長(zhǎng) ID 相同。
比如說(shuō)多進(jìn)程服務(wù),一般情況下都是共同協(xié)作 完成一個(gè)特定任務(wù),每一個(gè)進(jìn)程組都有一個(gè)組長(zhǎng),默認(rèn)進(jìn)程組 ID 與進(jìn)程組長(zhǎng) ID 相同
。
一個(gè)父進(jìn)程創(chuàng)建三個(gè)子進(jìn)程,很顯然肯定是父進(jìn)程是組長(zhǎng)
?
寫一個(gè)簡(jiǎn)單的程序
kill函數(shù)測(cè)試
kill 也有頭文件
kill自殺,
?打印這句話,看看能不能打印出來(lái),如果說(shuō)沒(méi)打印出來(lái),說(shuō)明這個(gè)進(jìn)程已經(jīng)死掉了,
?
父進(jìn)程能不能殺死子進(jìn)程啊?
可以
子進(jìn)程能不能殺死父進(jìn)程?
把進(jìn)程組的概念也說(shuō)一下
?
?
?嚴(yán)格的說(shuō)不是父進(jìn)程殺死子進(jìn)程,而是說(shuō)父進(jìn)程給子進(jìn)程發(fā)送信號(hào),kill這個(gè)函數(shù)其實(shí)不是殺死的意思,在這是給誰(shuí)誰(shuí)誰(shuí)發(fā)送信號(hào)的意思 或者子進(jìn)程殺死父進(jìn)程
?
這個(gè)是循環(huán)創(chuàng)建三個(gè)子進(jìn)程,
我先把這個(gè)進(jìn)程組的概念先給你提一句
為什么shellp(10) 讓他不退出,便于我們觀察
?
?
?
ps -ajx
第一個(gè)是父進(jìn)程,pid 這個(gè)是?
pid 是哪個(gè)進(jìn)程的
pgid是組id
sid是會(huì)話id
2016是這個(gè)kill1進(jìn)程的父進(jìn)程 他的父進(jìn)程應(yīng)該是-bash啊?
2369是他自己的pid
組的話也是2369他自己
他的會(huì)話id 2106 是不是bash啊?
2369 接下來(lái)這三個(gè)是不是都是子進(jìn)程啊?這三個(gè)子進(jìn)程很顯然 父進(jìn)程都是2306 子進(jìn)程自己的pid 各自都不一樣 ?組都是一樣的
2369 和pid 2369是一樣的 也就是說(shuō) 這三個(gè)子進(jìn)程 和這一個(gè)父進(jìn)程他們的組id就是父進(jìn)程的pid
會(huì)話id 也是同一會(huì)話,2106 是不是bash啊?
我們這四個(gè)進(jìn)程 當(dāng)然是包括一個(gè)父進(jìn)程 3個(gè)子進(jìn)程 在一個(gè)組當(dāng)中,也在一個(gè)會(huì)話當(dāng)中,實(shí)際上一個(gè)會(huì)話會(huì)可以包含一個(gè)或多個(gè)組