Linux下的timerfd在OS X下可以用什麼替代?
有一段代碼要從Linux遷移到OS X下,但是在timerfd上出了點問題,Google了很久也沒有找到解決方案。
取決於你現在使用timerfd的代碼是怎麼寫的。如果你還是想用read/select來獲取timeout,你可以單獨起一個線程來模擬timerfd的功能,再用pipe(2)來替換原來的 timerfd,時間到了就往pipe里寫8個位元組。
或者把timer的功能做到 reactor 里,控制 poll() 的第3個參數來實現 timer。可參考 muduo/backport.diff at master · chenshuo/muduo · GitHub
前幾天剛好看到這份代碼,下載這份代碼搜索timerfd.
GitHub - vonnyfly/tgt並不需要多線程。用setitimer + sigaction 來實現。
謝謝@陳碩 大大的問答,事實上最近的確在看《Linux 多線程伺服器編程——使用muduo C++網路庫》。
單獨起一個線程的方案,自己寫了個小類粗糙地封裝了一下,自己提的問題還是把自己的代碼貼上來吧,可能有錯誤哈://C++11
//TimerFd.h
class TimerFd
: public boost::noncopyable
{
private:
int pipeFd_[2];
std::atomic&
public:
TimerFd();
~TimerFd();
int GetFd() const;
void SetTime(const std::chrono::milliseconds timeout);
};
//TimerFd.cpp 在OS X下需要timerfd的初衷就是希望使定時器能和select、poll這些函數配合,現在通過這種比較簡單的方法基本實現了這個目的,有知友提到此方案由於線程的開銷可能會對計時精度造成影響,在我的MacBook(Intel Core i7 4@2.8GHz, 16GB)下測試計時誤差基本在萬分之四以內,本來也是自己寫著練手的小項目,這種精度應該足矣。至於timing wheel等方案,我現在只是知道大概原理,以後再試著加入吧。
TimerFd::TimerFd()
: isTiming_(false)
{
if(::pipe(pipeFd_) == -1)
{
LOG_FATAL &<&< "TimerFd not available.";
}
}
TimerFd::~TimerFd()
{
::close(pipeFd_[1]);
::close(pipeFd_[0]);
}
int TimerFd::GetFd() const
{
return pipeFd_[0];
}
void TimerFd::SetTime(const std::chrono::milliseconds timeout)
{
if(isTiming_)
{
LOG_ERROR &<&< "Timer is running.";
return;
}
auto timeoutMs = static_cast&
isTiming_ = true;
std::thread timer([this, timeoutMs]()
{
::poll(nullptr, 0, timeoutMs);
::write(pipeFd_[1], " ", 1);
isTiming_ = false;
});
timer.detach();
}
推薦閱讀:
※生信自學之linux操作基礎
※為什麼拷貝到U盤速度越來越慢?
※Linux系統安全
※【技術人快報189期】Linux補丁是「完全無用的垃圾」+上海銀行探索智能運維