日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux 信号之mysleep

發(fā)布時(shí)間:2023/12/20 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 信号之mysleep 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、????用alarm和pause實(shí)現(xiàn)sleep(3)函數(shù),稱為mysleep。

?

1. main函數(shù)調(diào)用mysleep函數(shù),后者調(diào)用sigaction注冊(cè)了SIGALRM信號(hào)的處理函數(shù)sig_alrm。

2. 調(diào)用alarm(seconds)設(shè)定鬧鐘。

3. 調(diào)用pause等待,內(nèi)核切換到別的進(jìn)程運(yùn)行。

4. seconds秒之后,鬧鐘超時(shí),內(nèi)核發(fā)SIGALRM給這個(gè)進(jìn)程。

5. 從內(nèi)核態(tài)返回這個(gè)進(jìn)程的用戶態(tài)之前處理未決信號(hào),發(fā)現(xiàn)有SIGALRM信號(hào),其處理函數(shù) 是sig_alrm。

6. 切換到用戶態(tài)執(zhí)行sig_alrm函數(shù),進(jìn)入sig_alrm函數(shù)時(shí)SIGALRM信號(hào)被自動(dòng)屏蔽, 從sig_alrm函數(shù)返回時(shí)SIGALRM信號(hào)自動(dòng)解除屏蔽。然后自動(dòng)執(zhí)行系統(tǒng)調(diào)用sigreturn再次進(jìn)入 內(nèi)核,再返回用戶態(tài)繼續(xù)執(zhí)行進(jìn)程的主控制流程(main函數(shù)調(diào)用的mysleep函數(shù))。

7. pause函數(shù)返回-1,然后調(diào)用alarm(0)取消鬧鐘,調(diào)用sigaction恢復(fù)SIGALRM信號(hào)以前的處理 動(dòng)作。

????????????? #include <stdio.h>

#include <signal.h>

#include <unistd.h>

?

void sig_alarm(int signo)//信號(hào)處理函數(shù)

{}

?

int mysleep(int seconds)

{

structsigaction act, oact;

act.sa_handler= sig_alarm;

sigemptyset(&act.sa_mask);

act.sa_flags= 0;

sigaction(SIGALRM,&act, &oact);//注冊(cè)信號(hào)處理函數(shù)

?

alarm(seconds);//設(shè)置鬧鐘

pause();

int_time = alarm(0);//清空鬧鐘

sigaction(SIGALRM,&oact,NULL);//恢復(fù)默認(rèn)信號(hào)處理動(dòng)作

return_time;

}

?

int main()

{

while(1)

{

??????? printf("iam sleeping !\n");

??????? mysleep(3);

?

}

return0;

}

運(yùn)行結(jié)果:每3秒打印一條語(yǔ)句


缺陷:在鬧鐘設(shè)置之后,響應(yīng)之前被切出去,再過(guò)3秒再切回來(lái),就將永遠(yuǎn)收不到信號(hào),進(jìn)程將被永遠(yuǎn)掛起。

思考問(wèn)題:

1、???????????信號(hào)處理函數(shù)sig_alrm什么都沒(méi)?干,為什么還要注冊(cè)它作為SIGALRM的處理函數(shù)?不注冊(cè)信號(hào)處 理函數(shù)可以嗎?

信號(hào)處理機(jī)制:

用函數(shù)signal注冊(cè)一個(gè)信號(hào)捕捉函數(shù)。原型為:


#include?
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
?
signal 的第1個(gè)參數(shù)signum表示要捕捉的信號(hào),第2個(gè)參數(shù)是個(gè)函數(shù)指針,表示要對(duì)該信號(hào)進(jìn)行捕捉的函數(shù),該參數(shù)也可以是SIG_DEF(表示交由系統(tǒng)缺省處理,相當(dāng)于白注冊(cè)了)或SIG_IGN(表示忽略掉該信號(hào)而不做任何處理)。signal如果調(diào)用成功,返回以前該信號(hào)的處理函數(shù)的地址,否則返回 SIG_ERR。


sighandler_t是信號(hào)捕捉函數(shù),由signal函數(shù)注冊(cè),注冊(cè)以后,在整個(gè)進(jìn)程運(yùn)行過(guò)程中均有效,并且對(duì)不同的信號(hào)可以注冊(cè)同一個(gè)信號(hào)捕捉函數(shù)。該函數(shù)只有一個(gè)參數(shù),表示信號(hào)值。

示例:

1)、? 捕捉終端CTRL+c產(chǎn)生的SIGINT信號(hào):
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
void SignHandler(int iSignNo)
{
??? printf("Capture sign no:%d/n",iSignNo);?
}
?
int main()
{
??? signal(SIGINT,SignHandler);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}
該程序運(yùn)行起來(lái)以后,通過(guò)按CTRL+c將不再終止程序的運(yùn)行。應(yīng)為CTRL+c產(chǎn)生的SIGINT信號(hào)已經(jīng)由進(jìn)程中注冊(cè)的SignHandler函數(shù)捕捉了。該程序可以通過(guò)Ctrl+/終止,因?yàn)榻M合鍵Ctrl+/能夠產(chǎn)生SIGQUIT信號(hào),而該信號(hào)的捕捉函數(shù)尚未在程序中注冊(cè)。

?

2)、? 忽略掉終端CTRL+c產(chǎn)生的SIGINT信號(hào):
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
int main()
{
??? signal(SIGINT,SIG_IGN);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}
該程序運(yùn)行起來(lái)以后,將CTRL+C產(chǎn)生的SIGINT信號(hào)忽略掉了,所以CTRL+C將不再能是該進(jìn)程終止,要終止該進(jìn)程,可以向進(jìn)程發(fā)送SIGQUIT信號(hào),即組合鍵CTRL+/
?
3)、? 接受信號(hào)的默認(rèn)處理,接受默認(rèn)處理就相當(dāng)于沒(méi)有寫信號(hào)處理程序:
?
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
?
int main()
{
??? signal(SIGINT,DEF);?
??? while(true)?
??????? sleep(1);?
??? return 0;?
}

2、為什么在mysleep函數(shù)返回前要恢復(fù)SIGALRM信號(hào)原來(lái)的sigaction?

?

??? ??? 當(dāng)某個(gè)信號(hào)的處理函數(shù)被調(diào)用時(shí),內(nèi)核自動(dòng)將當(dāng)前信號(hào)加入進(jìn)程的信號(hào)屏蔽字,當(dāng)信號(hào)處理函數(shù)返回時(shí)自動(dòng)恢復(fù)原來(lái)的信號(hào)屏蔽字,這樣就保證了在處理某個(gè)信號(hào)時(shí),如果這種信號(hào)再次產(chǎn)生,那么它會(huì)被阻塞到當(dāng)前處理結(jié)束為止。

?

?

?

二、? sigsuspend實(shí)現(xiàn)mysleep 函數(shù):

?

對(duì)于第一個(gè)版本的mysleep , 出現(xiàn)這個(gè)問(wèn)題的根本原因是系統(tǒng)運(yùn)行的時(shí)序(Timing)并不像我寫程序時(shí)所設(shè)想的那樣。雖然alarm(nsecs)緊接著的下?行就是pause(),但是?無(wú)法保證pause()?一定會(huì)在調(diào)用alarm(nsecs)之后的nsecs秒之內(nèi)被調(diào)?用。由于異步事件在任何時(shí)候都有可能發(fā)?生(這?的異步事件指出現(xiàn)更高優(yōu) 先級(jí)的進(jìn)程),如果我們寫程序時(shí)考慮不周密,就可能由于時(shí)序問(wèn)題而導(dǎo)致錯(cuò)誤,這叫做競(jìng)態(tài)條件 (Race Condition)。

?

sigsuspend包含了pause的掛起等待功能,同時(shí)解決了競(jìng)態(tài)條件的問(wèn)題,在對(duì)時(shí)序要求嚴(yán)格的場(chǎng)合下都應(yīng)該調(diào)?用sigsuspend而不是pause。

?

#include <signal.h>

int sigsuspend(const sigset_t *sigmask);

?

和pause?一樣,sigsuspend沒(méi)有成功返回值,只有執(zhí)?行了?一個(gè)信號(hào)處理函數(shù)之后sigsuspend才返回,返回值為-1,errno設(shè)置為EINTR。

?

調(diào)?用sigsuspend時(shí),進(jìn)程的信號(hào)屏蔽字由sigmask參數(shù)指定,可以通過(guò)指定sigmask來(lái)臨時(shí)解除 對(duì)某 個(gè)信號(hào)的屏蔽,然后掛起等待,當(dāng)sigsuspend返回時(shí),進(jìn)程的信號(hào)屏蔽字恢復(fù)為原來(lái)的值,如果原來(lái)對(duì)該信號(hào)是屏蔽的,從sigsuspend返回后仍然是屏蔽的。

?

以下?用sigsuspend重新實(shí)現(xiàn)mysleep函數(shù):

1、?????????屏蔽SIGALARM信號(hào)

2、?????????alarm(seconds);

3、?????????解除對(duì)SIGALARM信號(hào)的屏蔽。

4、?????????掛起等待pause();

#include <stdio.h>

#include <unistd.h>

#include <signal.h>

?

void sig_alarm(int signo)

{}

?

int mysleep(int seconds)

{

?????? structsigaction act, oact;

?????? sigset_tnewmask, oldmask, suspmask;

//設(shè)置信號(hào)處理函數(shù),保存以前的信息

?????? unsignedint unslept;

?????? act.sa_handler= sig_alarm;

?????? sigemptyset(&act.sa_mask);

?????? act.sa_flags= 0;

?????? sigaction(SIGALRM,&act, &oact);

?? //阻塞信號(hào),保存當(dāng)前的信號(hào)屏蔽字

?????? sigemptyset(&newmask);

?????? sigaddset(&newmask,SIGALRM);

?????? sigprocmask(SIG_BLOCK,&newmask, &oldmask);

?????? //屏蔽SIGALRM

?????? alarm(seconds);

?????? suspmask= oldmask;

?????? sigdelset(&suspmask,SIGALRM);

?????? sigsuspend(&suspmask);

//解除屏蔽,掛起等待//SIGALRM信號(hào)遞達(dá)后,sigsuspend返回,自動(dòng)恢復(fù)原來(lái)的屏蔽字,自動(dòng)恢復(fù)原來(lái)的屏蔽字,即再次屏蔽SIGMASK

int _time =alarm(0);

?????? sigaction(SIGALRM,&act, NULL);

//恢復(fù)默認(rèn)的信號(hào)處理動(dòng)作

?????? sigprocmask(SIG_SETMASK,&oldmask, NULL);

???? ?//重置信號(hào)屏蔽字,再次解除對(duì)SIGALRM的屏蔽。

?????? return_time;

}

?

int main()

{

?????? while(1)

?????? {

????????????? mysleep(5);

????????????? printf("iam sleeping !\n");

?????? }

?????? return0;

}

?

運(yùn)行結(jié)果:每隔五秒響應(yīng)動(dòng)作,打印語(yǔ)句。

總結(jié)

以上是生活随笔為你收集整理的Linux 信号之mysleep的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 三级成人在线 | 色综合天天综合网天天狠天天 | 激情伊人网 | 老地方在线观看免费动漫 | 中文字幕二区三区 | 91成年人视频| 国产三级国产精品 | 久操视频免费看 | 午夜影院在线 | 久久男人网 | 久久久在线 | 亚洲国产精一区二区三区性色 | 都市激情亚洲综合 | 精品久久九九 | 禁漫天堂在线 | 九九免费在线视频 | 国产美女久久久 | 精品一区二区在线看 | 精品人妻大屁股白浆无码 | 亚洲同性gay激情无套 | 五月激情小说网 | 51精品| www色天使| 一本色道久久综合亚洲精品小说 | 狠狠澡| 高清在线一区二区 | 日本一区二区在线视频 | 亚洲社区在线 | 亚洲AV永久无码国产精品国产 | 日韩在线电影一区 | 亚洲国产日韩在线 | 一级特黄aa大片免费播放 | 久久艹影院 | 国产一区二区三区麻豆 | 无码人妻精品一区二区三 | jizz在线播放| 本道久久 | 欧美性高潮视频 | 91深夜视频 | 五月天六月婷婷 | 国产精品久久久久久久久绿色 | 涩涩视频在线免费看 | 美梦视频大全在线观看高清 | 久久久久国产综合av天堂 | 性感美女一级片 | 懂爱av | 奴性女会所调教 | 在线草| 久久久久亚洲精品国产 | 色婷婷亚洲一区二区三区 | 久久久久久久久久一区 | 国产精品一区在线观看 | 大地资源二中文在线影视免费观看 | av网天堂| 91chinese在线| 香蕉污视频在线观看 | 善良的老师伦理bd中字 | 蜜乳av懂色av粉嫩av | 国产精品伦一区二区 | 日韩欧美手机在线 | 日本午夜一区二区三区 | 美女黄视频大全 | 国产欧美一区二区视频 | 视频国产在线 | 超碰v| 美国做爰xxxⅹ性视频 | 色香蕉在线视频 | 男生把女生困困的视频 | 一卡二卡在线视频 | 亚洲精品高清视频在线观看 | 免费在线观看av网站 | 欧美久久久 | 公侵犯人妻中文字慕一区二区 | 免费看黄在线观看 | 欧美乱妇狂野欧美在线视频 | 国产不卡在线 | 被两个男人吃奶三p爽文 | 天天色天天搞 | 午夜成人免费电影 | 国产午夜无码视频在线观看 | 白嫩初高中害羞小美女 | 亚洲一区视频 | 欧美国产在线看 | 国产一级久久 | 国产成人啪精品 | 熟女人妇 成熟妇女系列视频 | 性欧美欧美巨大69 | 男生和女生一起搞鸡 | 国产制服91一区二区三区制服 | 欧美性潮喷xxxxx免费视频看 | 日本精品在线播放 | 91口爆一区二区三区在线 | 91麻豆成人精品国产 | 午夜特片网 | 开心激情五月婷婷 | av图片在线观看 | 欧美色性视频 | 好邻居韩国剧在线观看 | 台湾一级视频 |