人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

Linux模擬實現(xiàn)sleep函數(shù)

發(fā)布日期:2022-08-08 12:20 | 文章來源:站長之家

先來說說工作原理,linux中的sleep函數(shù)能夠讓程序休眠一定的秒數(shù),到時間后自動恢復(fù)運行。

實現(xiàn)思路

設(shè)定睡眠的秒數(shù)
睡眠(掛起)
恢復(fù)運行

實現(xiàn)機制

設(shè)定睡眠的秒數(shù):采用alarm()函數(shù)設(shè)定需要睡眠的秒數(shù),到時間后鬧鐘會發(fā)送SIGALRM信號給當(dāng)前進程。但SIGALRM信號的默認(rèn)操作是殺死進程,所以我們需要對SIGALRM信號進行自定義處理。
睡眠:pause()函數(shù)會讓當(dāng)前進程掛起,直到收到信號才會出錯返回。

示例程序代碼:模擬實現(xiàn)sleep使當(dāng)前進程每2秒打印”hello yingying\n”

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void handler(int signo)//由于程序在睡眠期間什么也不做所以自定義處理函數(shù)不執(zhí)行任何操作
{
}
int mysleep(int time)
{
 sigset_t set;
 sigemptyset(&set);
 struct sigaction act;
 struct sigaction oact;
 act.sa_handler = handler;//自定義處理函數(shù)
 act.sa_mask = set;
 act.sa_flags = 0; 
 sigaction(SIGALRM,&act,&oact);//捕捉鬧鐘信號自定義處理動作
 alarm(time);//time秒后給進程發(fā)送信號
 pause();//掛起進程
 int _time = alarm(0);//如果程序被提前喚醒取消鬧鐘
 sigaction(SIGALRM,&oact,NULL);//恢復(fù)捕捉信號的原始狀態(tài)
 return _time;
}
int main()
{
 while(1)
 {
 printf("hello yingying\n");
 mysleep(2);
 }
 return 0;
}

問題分析

上述代碼在看似沒有問題可以實現(xiàn)我們需要的結(jié)果,但是帶 多執(zhí)行流下仍可以正常運行嗎?例如在設(shè)定了鬧鐘后當(dāng)前進程被切換出去,等再切換回來鬧鐘已經(jīng)響過了,那么當(dāng)前進程就會被永遠掛起。所以我們需要優(yōu)化上面的程序。

.優(yōu)化方案一:
1.屏蔽SIGALRM信號
2.alarm(time)
3.解除屏蔽SIGALRM信號
4.pause()

.優(yōu)化方案二:
1.屏蔽SIGALRM信號
2.alarm(time)
3.pause()
4.解除屏蔽SIGALRM信號

這兩種方案大家思考一下可行嗎?應(yīng)該選哪個呢?

方案選擇

對于方案一:如果進程在解除屏蔽之后,pause()之前的的間隙被切走仍會造成同樣的問題,進程也可能被永遠掛起。
對于方案二:程序掛起之后,鬧鐘信號被屏蔽,一直處于未決狀態(tài),程序無法收到信號,進程也就會被一直掛起。所以方案二是不可以選擇的。
對于方案一我們可以改進,使解除阻塞與掛起成為一個原子操作這樣就可以解決我們的問題了。

解決問題

像方案一這種由時序問題導(dǎo)致程序出現(xiàn)問題的情況成為競態(tài)條件。sigsuspend()函數(shù)可以實現(xiàn)pause()函數(shù)的掛起功能,同時也能解決競態(tài)條件的問題。sigsuspend()函數(shù)的功能就是-“解除信號屏蔽”-“掛起進程等待信號”-“執(zhí)行信號處理函數(shù)”- “出錯返回”。所以sigsuspend()函數(shù)函數(shù)同pause()函數(shù)一樣只有出錯返回值。在對程序時序要求比較嚴(yán)格的程序中一般使用sigsuspend()函數(shù)。

優(yōu)化后的程序代碼

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void handler(int signo)
{
}
int mysleep(int time)
{
 sigset_t set,oset,susmask;
 sigemptyset(&set);
 sigaddset(&set,SIGALRM);
 sigprocmask(SIG_BLOCK,&set,&oset);
 struct sigaction act;
 struct sigaction oact;
 act.sa_handler = handler;
 act.sa_mask = set;
 act.sa_flags = 0; 
 sigaction(SIGALRM,&act,&oact);
 alarm(time);
 susmask = oset;
 sigdelset(&susmask,SIGALRM);
 sigsuspend(&susmask);
 int _time = alarm(0);
 sigaction(SIGALRM,&oact,NULL);
 sigprocmask(SIG_BLOCK,&oset,NULL);
 return _time;
}
int main()
{
 while(1)
 {
 printf("hello yingying\n");
 mysleep(2);
 }
 return 0;
}

這樣我們的sleep函數(shù)的模擬實現(xiàn)就完成了。

程序結(jié)果

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持本站。

美國快速服務(wù)器

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部