欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2017年06月08日 09:37:05   作者:BabysBreath_hl  
這篇文章主要介紹了linux 下實(shí)現(xiàn)sleep詳解及簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下

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

sleep:

普通版本

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

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

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

   4>nsecs秒之后,鬧鐘超時(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ù)返回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)作。

2、實(shí)現(xiàn)代碼

#include<stdio.h> 
#include<signal.h> 
 
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 <unistd.h> 
int pause(void); 

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

sigaction函數(shù)

#include <signal.h> 
int sigaction(int signo, const struct sigaction *act, struct 
sigaction *oact); 

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

int sigemptyset(sigset_t *set); 

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

二、優(yōu)化版本

所需函數(shù)分析

#include <signal.h>
 
int sigsuspend(const sigset_t *sigmask); 

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

sigprocmask

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

#include <signal.h>
 
int sigprocmask(int how, const sigset_t *set, sigset_t *oset); 

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

how的選項(xiàng)意義


如果調(diào)⽤sigprocmask解除了對(duì)當(dāng)前若⼲個(gè)未決信號(hào)的阻塞,則在sigprocmask返回前,⾄少將其中⼀個(gè)信號(hào)遞達(dá)。

代碼實(shí)現(xiàn):

#include<stdio.h> 
#include<signal.h> 
 
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)問題。我們重新審視一下普通版本的時(shí)序問題。

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

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

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

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

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

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

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

在一個(gè)進(jìn)程運(yùn)行過程中,因?yàn)橛捎诋惒剑钥赡鼙黄渌麅?yōu)先級(jí)更高的進(jìn)程,由于時(shí)序問題而引發(fā)的錯(cuò)誤問題。這樣的問題稱為競態(tài)問題。

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

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • shell腳本讀取命令行參數(shù)的實(shí)現(xiàn)

    shell腳本讀取命令行參數(shù)的實(shí)現(xiàn)

    本文主要介紹了shell腳本讀取命令行參數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • linux基礎(chǔ)之Shell Script入門介紹

    linux基礎(chǔ)之Shell Script入門介紹

    本文介紹下,學(xué)習(xí)shell script編程的入門知識(shí),通過幾個(gè)入門實(shí)例,帶領(lǐng)大家走進(jìn)shell script的神圣殿堂,呵呵,有需要的朋友參考下
    2013-11-11
  • 一文詳解Linux?du命令的使用方法

    一文詳解Linux?du命令的使用方法

    在Linux系統(tǒng)中,du命令是一款功能強(qiáng)大且實(shí)用的工具,可用于查看文件和目錄的磁盤使用情況,本文將深入探討du命令的使用方法和一些常見選項(xiàng),以協(xié)助您更全面地理解和有效地管理系統(tǒng)中的存儲(chǔ)空間,需要的朋友可以參考下
    2024-02-02
  • shell中循環(huán)調(diào)用hive sql 腳本的方法

    shell中循環(huán)調(diào)用hive sql 腳本的方法

    今天小編就為大家分享一篇shell中循環(huán)調(diào)用hive sql 腳本的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • shell之定時(shí)周期性執(zhí)行腳本的方法示例

    shell之定時(shí)周期性執(zhí)行腳本的方法示例

    這篇文章主要介紹了shell之定時(shí)周期性執(zhí)行腳本的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • linux目錄管理方法介紹

    linux目錄管理方法介紹

    這篇文章介紹了linux目錄管理的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Shell腳本實(shí)現(xiàn)memcache緩存命中率監(jiān)控

    Shell腳本實(shí)現(xiàn)memcache緩存命中率監(jiān)控

    這篇文章主要介紹了Shell腳本實(shí)現(xiàn)memcache緩存命中率監(jiān)控,這個(gè)腳本比較簡單,通過check_tcp腳本獲取memcached的stats信息,然后將該信息格式化成一個(gè)字符串,然后將get_hits比上cmd_gets就能得到緩存命中率,需要的朋友可以參考下
    2014-12-12
  • awk 九九乘法表 shell實(shí)現(xiàn)代碼

    awk 九九乘法表 shell實(shí)現(xiàn)代碼

    這篇文章主要介紹了awk 九九乘法表 shell實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2016-03-03
  • Linux下find?命令的?7?種用法

    Linux下find?命令的?7?種用法

    Linux?下?find?命令在目錄結(jié)構(gòu)中搜索文件,并執(zhí)行指定的操作,Linux?下?find?命令提供了相當(dāng)多的查找條件,功能很強(qiáng)大,這篇文章主要介紹了find?命令的?7?種用法,需要的朋友可以參考下
    2022-12-12
  • shell腳本中執(zhí)行python腳本并接收其返回值的例子

    shell腳本中執(zhí)行python腳本并接收其返回值的例子

    這篇文章主要介紹了shell腳本中執(zhí)行python腳本并接收其返回值的例子,本文重點(diǎn)在于如何接收python腳本的返回值,需要的朋友可以參考下
    2014-08-08

最新評(píng)論