真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

linux下如何實現(xiàn)sleep-創(chuàng)新互聯(lián)

這篇文章給大家分享的是有關(guān)linux下如何實現(xiàn)sleep的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

創(chuàng)新互聯(lián)建站是一家集網(wǎng)站建設(shè),隆安企業(yè)網(wǎng)站建設(shè),隆安品牌網(wǎng)站建設(shè),網(wǎng)站定制,隆安網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,隆安網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

linux 下實現(xiàn)sleep詳解及簡單實例

sleep:

普通版本

1、基本設(shè)計思路:

   1>注冊SIGALRM信號的處理函數(shù);
   2>調(diào)用alarm(nsecs)設(shè)定鬧鐘;

   3>調(diào)?pause等待,內(nèi)核切換到別的進程運行;

   4>nsecs秒之后,鬧鐘超時,內(nèi)核發(fā)SIGALRM給這個進程 ;

   5>從內(nèi)核態(tài)返回這個進程的?戶態(tài)之前處理未決信號,發(fā)現(xiàn)有SIGALRM信號,其處理函數(shù)是sig_alrm;

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

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

2、實現(xiàn)代碼

#include 
#include 
 
void handler(int signo) 
{} 
 
int mysleep(int timeout) 
{ 
  struct sigaction act,oact; 
  act.sa_handler = handler; 
  act.sa_flags = 0; 
  sigemptyset(&act.sa_mask); 
 
  sigaction(SIGALRM,&act,&oact); 
  alarm(timeout); 
  pause(); 
  int ret = alarm(0); 
  sigaction(SIGALRM,&oact,NULL); 
  return ret; 
} 
 
int main() 
{ 
  while(1) 
  { 
    printf("using musleep!\n"); 
    mysleep(3); 
  } 
  return 0; 
}

相關(guān)函數(shù)分析:

#include  
int pause(void);

pause函數(shù)使調(diào)?進程掛起直到有信號遞達。如果信號的處理動作是終?進程,則進程終?,pause函數(shù)沒有機會返回;如果信號的處理動作是忽略,則進程繼續(xù)處于掛起狀態(tài),pause不返回;如果信號的處理動作是捕捉,則調(diào)?了信號處理函數(shù)之后pause返回-1,errno設(shè)置為EINTR, 所以pause只有出錯的返回值 。

sigaction函數(shù)

#include  
int sigaction(int signo, const struct sigaction *act, struct 
sigaction *oact);

sigaction函數(shù)可以讀取和修改與指定信號相關(guān)聯(lián)的處理動作。調(diào)?成功則返回0,出錯則返回- 1。 signo是指定信號的編號。若act指針?空,則根據(jù)act修改該信號的處理動作。若oact指針非 空,則通過oact傳出該信號原來的處理動作。


int sigemptyset(sigset_t *set);

函數(shù)sigemptyset初始化set所指向的信號集,使其中所有信號的對應(yīng)bit清零,表?該信號集不包含 任何有效信號。


二、優(yōu)化版本


所需函數(shù)分析

#include ? 
int sigsuspend(const sigset_t *sigmask);

sigsuspend沒有成功返回值,只有執(zhí)?了?個信號處理函數(shù)之后sigsuspend才返回,返回值為-1,errno設(shè)置為EINTR。調(diào)?sigsuspend時,進程的信號屏蔽字由sigmask參數(shù)指定,可以通過指定sigmask來臨時解除對某 個信號的屏蔽,然后掛起等待,當(dāng)sigsuspend返回時,進程的信號屏蔽字恢復(fù)為原來的值,如果原來對該信號是屏蔽的,sigsuspend返回后仍然是屏蔽的。
sigsuspend函數(shù)與pause函數(shù):都可以將程序掛起,但是sigsuspend函數(shù)可以實現(xiàn)對信號屏蔽字的解除與掛起。

sigprocmask


調(diào)?函數(shù)sigprocmask可以讀取或更改進程的信號屏蔽字(阻塞信號集)。

#include ? 
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

如果oset是?空指針,則讀取進程的當(dāng)前信號屏蔽字通過oset參數(shù)傳出。如果set是?空指針,則 更改進程的信號屏蔽字,參數(shù)how指?如何更改。如果oset和set都是?空指針,則先將原來的信號 屏蔽字備份到oset?,然后根據(jù)set和how參數(shù)更改信號屏蔽字。


how的選項意義

linux下如何實現(xiàn)sleep


如果調(diào)?sigprocmask解除了對當(dāng)前若?個未決信號的阻塞,則在sigprocmask返回前,?少將其中?個信號遞達。

代碼實現(xiàn):

#include 
#include 
 
void handler(int signo) 
{} 
 
int mysleep(int timout) 
{ 
  struct sigaction act,oact; 
  sigset_t newmask,oldmask,suspmask; 
  act.sa_handler = handler; 
  act.sa_flags = 0; 
  sigemptyset(&act.sa_mask); 
 
  sigaction(SIGALRM,&act,&oact); 
  sigemptyset(&newmask); 
  sigaddset(&newmask,SIGALRM); 
  sigprocmask(SIG_BLOCK,&newmask,&oldmask); 
 
  alarm(timout); 
 
  suspmask = oldmask; 
  sigdelset(&suspmask,SIGALRM); 
  sigsuspend(&suspmask); 
   
  int unslept = alarm(0); 
  sigaction(SIGALRM,&oact,NULL); 
  sigprocmask(SIG_SETMASK,&oldmask,NULL); 
  return(unslept); 
} 
int main() 
{ 
  while(1) 
  { 
    printf("using musleep!\n"); 
    mysleep(3); 
  } 
  return 0; 
}

優(yōu)化版本解決了普通版本存在的競態(tài)問題。我們重新審視一下普通版本的時序問題。


1、設(shè)置SIGALRM信號的處理函數(shù);

2、調(diào)用alarm()函數(shù)設(shè)置鬧鐘;

3、內(nèi)核選取更高優(yōu)先級的進程來取代當(dāng)前進程,并且這樣的進程很多,同時執(zhí)行時間又很長;

4、鬧鐘超時了,內(nèi)核發(fā)送SIGALRM信號給該進程,并且處于未決狀態(tài);

5、優(yōu)先級更高的進程結(jié)束后,內(nèi)核要調(diào)度回這個進程執(zhí)?。 SIGALRM信號遞達,執(zhí)?處理函 數(shù)sig_alrm之后再次進?內(nèi)核。

6、返回這個進程的主控制流程,alarm(nsecs)返回,調(diào)?pause()掛起等待。

7、可是現(xiàn)在SIGALRM信號已經(jīng)被處理,進程會導(dǎo)致錯誤。

在一個進程運行過程中,因為由于異步,所以可能被其他優(yōu)先級更高的進程,由于時序問題而引發(fā)的錯誤問題。這樣的問題稱為競態(tài)問題。


優(yōu)化版本中,先將設(shè)置SIGALRM信號的處理函數(shù),然后將SIGALRM信號進行屏蔽,然后調(diào)用alarm()函數(shù)設(shè)置鬧鐘,然后調(diào)用sigprocmask()函數(shù)對SIGALRM信號解除屏蔽然后掛起等待,這樣就解決了競態(tài)問題。

感謝各位的閱讀!關(guān)于“l(fā)inux下如何實現(xiàn)sleep”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


名稱欄目:linux下如何實現(xiàn)sleep-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://weahome.cn/article/cejosd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部