新聞中心
在Linux操作系統(tǒng)中,alarm()函數(shù)是用來(lái)設(shè)置一個(gè)定時(shí)器來(lái)喚醒進(jìn)程的。它的原型如下:

unsigned int alarm(unsigned int seconds);
這個(gè)函數(shù)會(huì)在指定的時(shí)間(以秒為單位)后將SIGALRM信號(hào)發(fā)送給當(dāng)前進(jìn)程。當(dāng)收到這個(gè)信號(hào)時(shí),進(jìn)程就會(huì)被喚醒(如果它正在阻塞SIGALRM信號(hào))。通常情況下,在調(diào)用alarm()函數(shù)后進(jìn)程會(huì)被掛起等待一段時(shí)間,然后被SIGALRM信號(hào)喚醒。
然而,在一些情況下,我們可能會(huì)遇到一個(gè)奇怪的問(wèn)題:alarm()函數(shù)會(huì)執(zhí)行兩次。這種情況會(huì)導(dǎo)致進(jìn)程在沒(méi)有等到預(yù)定時(shí)間到達(dá)的情況下就被喚醒,從而破壞了計(jì)時(shí)器的效果。
那么,為什么會(huì)發(fā)生這種情況呢?有以下幾個(gè)原因:
1. 信號(hào)的處理方式
我們需要了解一下Linux中信號(hào)的處理方式。當(dāng)進(jìn)程收到一個(gè)信號(hào)時(shí),它會(huì)被掛起,處理信號(hào)的函數(shù)會(huì)被調(diào)用。在函數(shù)執(zhí)行完畢后,進(jìn)程會(huì)返回到之前被中斷的代碼處繼續(xù)執(zhí)行。然而,在某些情況下,如果信號(hào)處理函數(shù)執(zhí)行時(shí)間太長(zhǎng),那么這個(gè)進(jìn)程可能會(huì)錯(cuò)過(guò)下一個(gè)alarm()函數(shù)的到期時(shí)間。
2. SA_RESTART標(biāo)記
另一個(gè)可能導(dǎo)致alarm()函數(shù)執(zhí)行兩次的原因是SA_RESTART標(biāo)記。這個(gè)標(biāo)記可以讓進(jìn)程在收到信號(hào)后重新啟動(dòng)被中斷的系統(tǒng)調(diào)用。這個(gè)標(biāo)記通常用在需要長(zhǎng)時(shí)間運(yùn)行的系統(tǒng)調(diào)用中,例如accept()函數(shù)。如果我們?cè)诎惭bSIGALRM信號(hào)處理程序時(shí)設(shè)置了SA_RESTART標(biāo)記,那么在alarm()函數(shù)到期后,進(jìn)程如果正在阻塞SIGALRM信號(hào)的話,它會(huì)嘗試重新啟動(dòng)之前的系統(tǒng)調(diào)用,這可能導(dǎo)致第二次調(diào)用alarm()。
3. 信號(hào)處理程序的不可重入性
有些信號(hào)處理程序是不可重入的,這意味著它們不能被中斷和再次執(zhí)行。如果我們安裝了一個(gè)不可重入的處理程序來(lái)處理SIGALRM信號(hào),那么這個(gè)程序如果被中斷,進(jìn)程可能會(huì)再次調(diào)用alarm()函數(shù)。
以上三個(gè)原因是導(dǎo)致alarm()函數(shù)執(zhí)行兩次的主要原因。如果我們想要避免這種問(wèn)題,在編寫(xiě)信號(hào)處理程序時(shí)我們需要特別小心。我們應(yīng)該盡量保持處理函數(shù)的簡(jiǎn)短,避免在函數(shù)中進(jìn)行耗時(shí)的操作。同時(shí),我們應(yīng)該盡可能地減少在信號(hào)處理程序中使用的庫(kù)函數(shù),這可以降低程序出錯(cuò)的風(fēng)險(xiǎn)。
alarm()函數(shù)是一個(gè)非常有用的功能,但是如果不小心編寫(xiě)信號(hào)處理程序,就可能導(dǎo)致它執(zhí)行兩次。因此,在使用它時(shí),我們應(yīng)該認(rè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-86922220linux 下進(jìn)程間通過(guò)信號(hào)進(jìn)行通信的具體實(shí)現(xiàn)過(guò)程
kill函數(shù)用來(lái)發(fā)送信號(hào)給指定的進(jìn)程,在Shell下輸入man 2 kill可獲取其函數(shù)原型如下:
#include
#include
int kill(pid_t pid,int sig);
該函數(shù)的行為與之一個(gè)參數(shù)pid的取值有關(guān),第二個(gè)參數(shù)sig表示信號(hào)編號(hào)。
如果pid是正數(shù),則發(fā)送信號(hào)sig給進(jìn)程號(hào)為pid的進(jìn)程;
如果pid為0,則發(fā)送信號(hào)sig給當(dāng)前進(jìn)程所屬進(jìn)程組里的所絕拿有進(jìn)程;
如果pid為-1,則把信號(hào)sig廣播至系統(tǒng)內(nèi)除1號(hào)進(jìn)程(init進(jìn)程)和自身以外的所有進(jìn)程;
如果pid是-1還小的負(fù)數(shù)高桐,則發(fā)送信號(hào)sig給屬于進(jìn)程組-pid的所有進(jìn)程。
如果參數(shù)sig是0,則kill()仍執(zhí)行正常的錯(cuò)誤檢查,但不發(fā)送信號(hào)??梢岳眠@一點(diǎn)來(lái)確定某進(jìn)程是否有權(quán)向另外一個(gè)進(jìn)程發(fā)送信號(hào)。如果向一個(gè)并不存在的進(jìn)程發(fā)送空信號(hào),則kill()返回-1,errno則被設(shè)置為ESRCH。
函數(shù)執(zhí)行成功返回0,當(dāng)有錯(cuò)誤發(fā)生并念搭時(shí)則返回-1,錯(cuò)誤代碼存入errno中,詳細(xì)的錯(cuò)誤代碼說(shuō)明請(qǐng)參考man手冊(cè)。
注意:只有具有root權(quán)限的進(jìn)程才能向其他任一進(jìn)程發(fā)送信號(hào),非root權(quán)限的進(jìn)程只能向?qū)儆谕粋€(gè)組或同一個(gè)用戶的進(jìn)程發(fā)送信號(hào)。
更簡(jiǎn)單的方法是通過(guò)進(jìn)程名給進(jìn)程發(fā)信號(hào)。比如你的進(jìn)程名是 aproc,你自己定義一個(gè)信號(hào)量18,那么:
#include
#include
#include
#include
char cmd=””; int sig = 18;
char procname=”aproc”;
sprintf(cmd, “killall -%d %s\n”, sig, procname);
system(cmd);
就能給特定進(jìn)程發(fā)信號(hào)了
linux 執(zhí)行兩次alarm的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux 執(zhí)行兩次alarm,Linux下為什么會(huì)執(zhí)行兩次alarm?,linux 下進(jìn)程間通過(guò)信號(hào)進(jìn)行通信的具體實(shí)現(xiàn)過(guò)程的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站建設(shè)選創(chuàng)新互聯(lián)(?:028-86922220),專業(yè)從事成都網(wǎng)站制作設(shè)計(jì),高端小程序APP定制開(kāi)發(fā),成都網(wǎng)絡(luò)營(yíng)銷推廣等一站式服務(wù)。
網(wǎng)站題目:Linux下為什么會(huì)執(zhí)行兩次alarm?(linux執(zhí)行兩次alarm)
網(wǎng)站地址:http://www.dlmjj.cn/article/dpococp.html


咨詢
建站咨詢
