Linux中的sleep、usleep、nanosleep、poll和select
在進行Linux C/C++程式設計時,可呼叫的sleep函式有好多個,那麼究竟應當呼叫哪一個了?下表列出了這幾個函式間的異同點,可作為參考:
|
性質 |
精準度 |
執行緒安全 |
訊號安全 |
|
sleep |
libc庫函式 |
秒 |
是 |
不能和alarm同時使用 |
有些是基於alarm實現的,所以不能和alarm同時使用 |
usleep |
libc庫函式 |
微秒 |
- |
- |
POSIX.1-2001已將usleep標註為廢棄,POSIX.1-2008已刪除usleep,應當使用nanosleep替代usleep |
nanosleep |
系統呼叫 |
納秒 |
是 |
不確定 |
即使被訊號中斷,也可實現實際睡眠時長不小於引數指定時長 |
clock_nanosleep |
系統呼叫 |
納秒 |
是 |
不確定 |
區別於nanosleep,可選擇為相對或絕對時間,其次是可以選擇使用哪個時鐘 |
poll |
系統呼叫 |
毫秒 |
是 |
是 |
在協程庫libco中可安全使用,如被訊號中斷,則實際睡眠時長會小於引數指定的時長 |
ppoll |
系統呼叫 |
納秒 |
是 |
是 |
如被訊號中斷,則實際睡眠時長會小於引數指定的時長 |
select |
系統呼叫 |
微秒 |
是 |
是 |
即使被訊號中斷,也可實現實際睡眠時長不小於引數指定時長 |
pselect |
系統呼叫 |
納秒 |
是 |
是 |
如被訊號中斷,則實際睡眠時長會小於引數指定的時長 |
C/C++常用封裝:
1) 基於nanosleep的毫秒級封裝
#include <time.h> void millisleep(uint32_t milliseconds) { struct timespec ts = { milliseconds / 1000, (milliseconds % 1000) * 1000000 }; while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno)); } |
2) 基於nanosleep的微秒級封裝
#include <time.h> void microsleep(uint32_t microseconds) { struct timespec ts = { microseconds / 1000000, (microseconds % 1000000) * 1000 }; while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno)); } |
3) 基於poll的秒級封裝
// 可libco協程庫中安全使用 void pollsleep(int milliseconds) { (void)poll(NULL, 0, milliseconds); } |
4) 基於select的毫秒級封裝
void selectsleep(int milliseconds) { struct timeval timeout = { milliseconds / 1000, (milliseconds % 1000) }; struct timeval old_timeout = { timeout.tv_sec, timeout.tv_usec }; while (true) { (void)select(0, NULL, NULL, NULL, &timeout); if (timeout.tv_sec<=0 && timeout.tv_usec<=0) break; } } |
如果開發環境是C++11或更高版本,則可直接使用C++標準庫提供的:
5) 毫秒睡眠
#if __cplusplus >= 201103L #include <chrono> #include <system_error> #include <thread>
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); #endif // __cplusplus >= 201103L |
6) 微秒睡眠
#if __cplusplus >= 201103L #include <chrono> #include <system_error> #include <thread>
std::this_thread::sleep_for(std::chrono::microseconds(1000)); #endif // __cplusplus >= 201103L |
上述介紹的sleep函式均不方便控制它們提前結束,如果需要這種sleep,可基於pthread_cond_timedwait實現,實現可參考CEvent原始碼:
https://github.com/eyjian/libmooon/blob/master/src/sys/event.cpp |
相關文章
- linux的sleep()和usleep()的使用和區別Linux
- 聊聊select, poll 和 epoll_waitAI
- Linux IO模式及 select、poll、epoll詳解Linux模式
- IO模式 select、poll、epoll模式
- Linux中Sleep和Wait命令的使用方式LinuxAI
- select、poll、epoll之間的區別
- 《UNIX網路程式設計》筆記 - select和poll程式設計筆記
- select、poll、epoll之間的區別總結[整理]
- linux中sleep詳解例項Linux
- Linux作業系統 sleep(0)、sleep(1)和sleep(-1)的區別,他們各有什麼作用Linux作業系統
- Linux IO模式及 select、poll、epoll詳解(含部分例項原始碼)Linux模式原始碼
- selec和poll的區別
- 伺服器IO多路複用的select和poll的區別以及監聽套接字select函式的四個宏操作伺服器函式
- IO多路複用——深入淺出理解select、poll、epoll的實現
- linux系統下poll和epoll核心原始碼剖析Linux原始碼
- 伺服器程式設計——I/O複用(select、poll、epoll)伺服器程式設計
- java yield()和sleep()的區別Java
- Linux中select()函式分析Linux函式
- 面試官:select、poll、epoll有何區別?我:阿巴阿巴...面試
- I/O Mutiplexing poll 和 epoll
- 面試題總結:Queue 中 poll()和 remove()有什麼區別?面試題REM
- sleep()和wait()區別AI
- Thead物件的sleep方法,和yield方法有何區別,為什麼實現的執行緒中,在run方法中要呼叫sleep方法?物件執行緒
- linux與windows下C++的sleep函式LinuxWindowsC++函式
- select into from 和 insert into select 的用法和區別
- Linux select()Linux
- java nio中的select和channel是怎麼使用的?Java
- JQuery 獲取select被選中的value和textjQuery
- 延時函式delay() sleep() Sleep()函式
- select * 和 select 所有欄位的區別
- select count(*)和select count(1)的區別
- SQLite中的SELECT子句SQLite
- HTML中Select的使用HTML
- DataTable中的select()用法
- Linux : select()詳解 和 實現原理【轉】Linux
- C#中Thread.Sleep()的作用及用法C#thread
- SQL中呼叫包含dbms_lock.sleep的函式SQL函式
- Task.Delay 和 Thread.Sleep 的區別thread