再談 Linux下的nanosleep函式

2021-07-03 04:24:52 字數 1744 閱讀 9759

int nanosleep(const struct timespec *req,struct timespec *rem);

struct timespec ;

這個函式功能是暫停某個程序直到你規定的時間後恢復,引數req就是你要暫停的時間,其中req->tv_sec是以秒為單位,而tv_nsec以納秒為單位(10的-9次方秒)。由於呼叫nanosleep是使程序進入task_interruptible,這就意味著有可能會沒有等到你規定的時間就因為其它訊號而喚醒,此時函式返回-1,且剩餘的時間會被記錄在rem中。

這個函式的實現是:將其狀態設定成task_interruptible,脫離就緒佇列,然後進行一次程序排程再由核心在規定的時間後傳送訊號來喚醒這個程序。

我們假設時鐘種中斷是10納秒一次,如果tv_sec = 0, tv_nsec = 2,那麼時鐘中斷一定是在10納秒後來喚醒這個程序的,這裡我們看到任務的重新排程最少是在10納秒之上,因此此函式的精確程度與時鐘頻率有關係,不過我們一般也不會延時在中斷級別的時間範圍內。

下面我們再來比較linux下nanosleep() 和usleep、sleep()的區別

sleep()

usleep()

nanosleep()

sleep()和nanosleep()都是使程序睡眠一段時間後被喚醒,但是二者的實現完全不同。

linux中並沒有提供系統呼叫sleep(),sleep()是在庫函式中實現的,它是通過呼叫alarm()來設定報警時間,呼叫sigsuspend()將程序掛起在訊號sigalarm上。

nanosleep()則是linux中的系統呼叫,它是使用定時器來實現的,該呼叫使呼叫程序睡眠,並往定時器佇列上加入乙個timer_list型定時器,time_list結構裡包括喚醒時間以及喚醒後執行的函式,通過nanosleep()加入的定時器的執行函式僅僅完成喚醒當前程序的功能。系統通過一定的機制定時檢查這些佇列(比如通過系統呼叫陷入核心後,從核心返回使用者態前,要檢查當前程序的時間片是否已經耗盡,如果是則呼叫schedule()函式重新排程,該函式中就會檢查定時器佇列,另外慢中斷返回前也會做此檢查),如果定時時間已超過,則執行定時器指定的函式喚醒呼叫程序。當然,由於系統時間片可能丟失,所以nanosleep()精度也不是很高。

另外alarm()也是通過定時器實現的,但是其精度只精確到秒級,另外,它設定的定時器執行函式是在指定時間向當前程序傳送sigalrm訊號。

總結一下

sleep 時間單位是秒

usleep的時間單位是微秒

select的精度是微妙,精確

struct timeval delay;

delay.tv_sec = 0;

delay.tv_usec = 20 * 1000; // 20 ms

select(0, null, null, null, &delay);

usleep()有有很大的問題

在一些平台下不是執行緒安全,如hp-ux以及linux

usleep()會影響訊號

在很多平台,如hp-ux以及某些linux下,當引數的值必須小於1 * 1000 * 1000也就是1秒,否則該函式會報錯,並且立即返回。

大部分平台的幫助文件已經明確說了,該函式是已經被捨棄的函式。

還好,posix規範中有乙個很好用的函式,nanosleep(),該函式沒有usleep()的這些缺點,它的精度是納秒級。在solaris的多執行緒環境下編譯器會自動把usleep()連線成nanosleep()。

linux下短延時推薦使用select函式,因為準確。

再談Oracle在Windows下的許可權問題

在上篇 oracle9i資料庫連線訪問的解決方法 我有寫過乙個關於asp.net訪問oracle9i資料庫的時候出現的許可權問題。錯誤提示是 無法載入 dll oci.dll 或未找到 oracle 客戶端和網路元件 今天又碰到同樣的許可權問題,錯誤提示是 could not create an e...

再談WINXP下的檔案共享問題!

最近一直有朋友在問winxp下檔案共享問題,比如如何實現guest使用者訪問共享,如何保證共享的安全等。其實這已經是乙個老話題了,今天閒暇,寫一寫,有需要的朋友可以作為參考。環境 工作組,所有計算機允可以網路連通。注 如果是域環境,所有的計算機是可以互相訪問資源的 當然不要開相應的防火牆設定即可 拓...

再談一下DOMContentLoad事件

這個問題算是個老問題了。所以,標題加上乙個再字。我主要說一下模擬這個事件時候容易出現的問題。對於ff,opera9,原生domcontentload支援,就不說了,最頭疼的是ie。我最初考慮這個問題的時候,想到的是document的readystate屬性。一下dojo的原始碼,發現它也是基於這個屬...