2017-06-01 95 views
0

我想在OSX上每N毫秒(理想情況下爲1)獲得一個回調。我已經成立了一個CFRunLoop,然後添加一個定時器,像這樣:OSX上的定時器回調

const double period = 0.001; 

CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); 

CFRunLoopTimerContext context; 
std::memset(&context, 0, sizeof(context)); 
context.info = ...; 

CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, now + period, period, 0, 0, RunLoopTimerCallBack, &context); 

// Add it to the loop. 
CFRunLoopAddTimer(/* my run loop reference */, timerRef, kCFRunLoopDefaultMode); 

看來工作 - 我RunLoopTimerCallback()被稱爲大約每毫秒。除非沒有。 documentation for CFRunLoopTimerCreate說:

如果存在實施原因,則可以通過計時器稍微調整間隔的精確度(最多亞毫秒)。

所以我期待它或多或少地工作,但在實踐中,我得到了8毫秒的回調之間的延遲:

delay graph

我試過setting the run loop thread to real-time priority,但它並沒有任何差異。有沒有人有任何想法,爲什麼我會得到這些延誤?我意識到這是推動操作系統相當辛苦,也許這是一些調度的事情,但仍然... 1毫秒不是短。

回答

0

其實我是一個白癡。設置實時線程優先級會產生巨大差異。下面是結果:

millisecond!

,這裏是我使用的代碼:

#include <mach/mach_time.h> 
#include <mach/thread_policy.h> 

#include <iostream> 
using namespace std; 

void SetPriorityRealtime() 
{ 
    mach_timebase_info_data_t timebase; 
    kern_return_t kr = mach_timebase_info(&timebase); 
    if (kr != KERN_SUCCESS) 
    { 
     cerr << "Warning: Couldn't get timebase." << endl; 
     return; 
    } 

    // The number of nanoseconds per tick is: 
    cerr << timebase.numer << "/" << timebase.denom << endl; 

    // Set the thread priority. 
    thread_time_constraint_policy ttcpolicy; 
    thread_port_t threadport = pthread_mach_thread_np(pthread_self()); 

    // In ticks. Therefore to convert nanoseconds to ticks multiply by (timebase.denom/timebase.numer). 
    ttcpolicy.period = 500 * 1000 * timebase.denom/timebase.numer; // Period over which we demand scheduling. 
    ttcpolicy.computation = 100 * 1000 * timebase.denom/timebase.numer; // Minimum time in a period where we must be running. 
    ttcpolicy.constraint = 100 * 1000 * timebase.denom/timebase.numer; // Maximum time between start and end of our computation in the period. 
    ttcpolicy.preemptible = FALSE; 

    kr = thread_policy_set(threadport, THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&ttcpolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT); 
    if (kr != KERN_SUCCESS) 
    { 
     cerr << "Warning: Couldn't set thread policy: " << kr << endl; 
     return; 
    } 
} 

說實話,我還是不能完全肯定的thread_time_constraint_policy成員是如何影響的事情。但至少這表明這是可能的。現在在Windows上做...