多執行緒中定時器的使用

2021-06-05 22:42:59 字數 2970 閱讀 8925

不管是在程序還是執行緒,很多時候我們都會使用一些定時器之類的功能,這裡就定時器在多執行緒的使用說一下。首先在linux程式設計中定時器函式有alarm()和setitimer(),alarm()可以提供乙個基於秒的定時功能,而setitimer可以提供乙個基於微妙的定時功能。

alarm()原型:

#include

unsigned int alarm(unsigned int seconds);

這個函式在使用上很簡單,第一次呼叫這個函式的時候是設定定時器的初值,下一次呼叫是重新設定這個值,並會返回上一次定時的剩餘時間。

setitimer()原型:

#include

int setitimer(int which, const struct itimerval *value,struct itimerval *ovalue);

這個函式使用起來稍微有點說法,首先是第乙個引數which的值,這個引數設定timer的計時策略,which有三種狀態分別是:

itimer_real:使用系統時間來計數,時間為0時發出sigalrm訊號,這種定時能夠得到乙個精準的定時,當然這個定時是相對的,因為到了微秒級別我們的處理器本身就不夠精確。

itimer_virtual:使用程序時間也就是程序分配到的時間片的時間來計數,時間為0是發出sigvtalrm訊號,這種定時顯然不夠準確,因為系統給程序分配時間片不由我們控制。

itimer_prof:上面兩種情況都能夠觸發

第二個引數引數value涉及到兩個結構體:

struct itimerval ;

struct timeval ;

在結構體itimerval中it_value是定時器當前的值,it_interval是當it_value的為0後重新填充的值。而timeval結構體中的兩個變數就簡單了乙個是秒乙個是微秒。

上面是這兩個定時函式的說明,這個函式使用本不是很難,可以說是很簡單,但是碰到具體的應用的時候可能就遇到問題了,在多程序程式設計中使用一般不會碰到什麼問題,這裡說的這些問題主要體現在多執行緒程式設計中。比如下面這個程式:

#include #include #include #include #include #include void sig_handler(int signo)

void *pthread_func()

}int main(int argc, char **argv)

while(1)

return 0;

}

這個程式的理想結果是:

main thread

alarm signal

alarm signal

alarm signal

alarm signal

alarm signal

main thread

可事實上並不是這樣的,它的結果是:

main pthread

alarm signal

main pthread

alarm signal

main pthread

為什麼會出現這種情況呢?是因為傳送給工作執行緒的訊號中斷的主線程的sleep,並且這個中情況只影響主線程而不會影響到其他的工作執行緒。我們怎麼才能解決這種問題呢,最簡單的方法是修改這個程式,修改這個執行緒主線程使用alarm,工作執行緒使用sleep。這樣就能夠達到我們的要求,但是有時候有不能簡單的這樣操作。所以我們就需要進一步的修改我們的程式。在這裡我第乙個想到的是使用signal(sigalrm, sig_ign),可是這個是設定整個程序對這個訊號的響應方式,經過測試也確實不能完成我期望的功能,那麼怎麼辦呢?有這樣乙個函式pthread_sigmask,執行緒中的訊號遮蔽,函式的原型及相關函式為:

#include

int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);

函式中第乙個引數how有三個值sig_block、sig_setmask和sig_unblock這裡我們是用第二個值sig_setmask

int sigemptyset(sigset_t *set); /*清除訊號集合set*/

int sigaddset(sigset_t *set, int signum); /*新增訊號signum到訊號集set中*/

然後我們改造我們的程式為:

#include #include #include #include #include #include void sig_handler(int signo)

void *pthread_func()

}int main(int argc, char **argv)

sigset_t sigset;

sigemptyset(&sigset);

sigaddset(&sigset, sigalrm);

pthread_sigmask(sig_setmask,&sigset,null);

while(1)

return 0;

}

這個時候我們就能夠看到我們想要的結果了。

這裡再附乙個setitimer的使用範例:

#include #include #include #include #include #include struct itimerval timerval;

void sig_handler(int signo)

void *pthread_func()

}int main(int argc, char **argv)

sigset_t sigset;

sigemptyset(&sigset);

sigaddset(&sigset, sigalrm);

pthread_sigmask(sig_setmask,&sigset,null);

while(1)

return 0;

}

多執行緒中定時器的使用

曹忠明 華清遠見嵌入式學院講師 不管是在程序還是執行緒,很多時候我們都會使用一些定時器之類的功能,這裡就定時器在多執行緒的使用說一下。首先在 linux 程式設計中定時器函式有 alarm 和setitimer alarm 可以提供乙個基於秒的定時功能,而 setitimer 可以提供乙個基於微妙的...

linux 多執行緒中定時器的使用

在開發linux mjpg streamer程式的時候,使用signal,奇怪的是程式竟然退出了。後來讀了曹老師的文章,才解決了這個問題。所以收錄到自己的部落格裡。呵呵 2010 10 14 19 47 29 曹忠明 華清遠見嵌入式學院講師 不管是在程序還是執行緒,很多時候我們都會使用一些定時器之類...

qt中定時器和多執行緒的使用

定時器和多執行緒的使用 注意 建立多執行緒需要加上新的執行緒類 1 建立乙個新的執行緒類mythread 標頭檔案.h ifndef mythread h define mythread h include class mythread public qthread endif mythread h...