我正在將我們的一個嵌入式微控制器庫移植到linux上,並在其周圍編寫一個python包裝器。SIGALRM,間隔定時器和睡眠問題()
我的低級模塊之一取決於每10ms調用一次回調。這個回調計數每個軟件定時器都有自己的回調。這些計時器在我們的圖書館中使用,儘管它們不必百分之百準確,但它們預計會持續滴答,並有望達到+/- 10%的準確度。該模塊模仿微控制器內的標準定時器中斷。
我有一個現有的實現使用setitimer和SIGALRM處理程序,它奇妙地工作。下面是我的一些代碼:
void halCounterInit(void)
{
struct sigaction alrm_action;
alrm_action.sa_handler = timerInterrupt;
alrm_action.sa_flags = SA_RESTART;
sigaction(SIGALRM, &alrm_action, NULL);
}
void halCounterEnable(void)
{
mytime.it_interval.tv_sec = 0;
mytime.it_interval.tv_usec = 10000; //10ms
mytime.it_value.tv_sec = 0;
mytime.it_value.tv_usec = 10000; //10ms
setitimer(ITIMER_REAL, &mytime, NULL);
}
void halCounterDisable(void)
{
mytime.it_interval.tv_sec = 0;
mytime.it_interval.tv_usec = 0;
mytime.it_value.tv_sec = 0;
mytime.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &mytime, NULL);
}
void halCounterRegisterInterruptHandler(InterruptHandlerCallback cb, void *params)
{
myInterruptHandler = cb;
myParams = params;
}
void timerInterrupt(int signum)
{
if (myInterruptHandler != NULL)
{
myInterruptHandler(myParams);
}
}
在測試一些該代碼與其他代碼一起的,我注意到調用睡覺()揪出來早產生SIGALRM信號時。我在python中使用ctypes與gevent(基於libevent)接口,以便在C庫上創建一個新圖層。我擔心這個SIGALRM問題會導致很難找到Python中的錯誤。
我試圖用一個pthread和一個阻塞select()調用來重寫我的簡單計數器,但看起來select()調用提前退出,我的計時器變得非常不準確。
- 有沒有辦法讓setitimer生成一個我可以捕獲的信號,而不是sigalrm?
- 有沒有另一種方法來做到這一點,而不使用信號?我已經嘗試了睡眠,在另一個線程中選擇和定期睡眠,但那不太好。
任何幫助表示讚賞。理想情況下,這對OSX和Linux都有效,但Linux是唯一的硬性要求。
編輯:使用select()或了nanosleep
我的單獨的線程代碼()。兩者都不準確。選擇的實現被註釋掉。 MyTime在init函數中正確配置。這是線程功能:
while (TRUE)
{
pthread_mutex_lock(&Lock);
//we are paused
while(!Running)
{
//we are waiting for a signal to tell us when to start again
pthread_cond_wait(&Cond, &Lock);
}
pthread_mutex_unlock(&Lock);
RemTime.tv_nsec = 0;
do
{
nanosleep(&MyTime, &RemTime);
}
while(RemTime.tv_nsec != 0);
//select(0, NULL, NULL, NULL, &MyTime);
if (myInterruptHandler != NULL)
{
myInterruptHandler(myParams);
}
}
謝謝。
Re#1,是的,但這是棘手的要做的正確(tm)作爲@abligh建議下面,尤其是在_library_代碼(它不能斷言信號的自由控制)棘手。 Re#2,是的,但我們無法幫助您調試我們無法看到的代碼。 (順便說一句,SIGALRM或SIGVTALRM?你的敘述和你的代碼說了不同的東西。) – pilcrow
@pilcrow,SIGALRM,我剛剛意識到我複製了一些我正在玩的調試代碼。將編輯。 –