<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 多線(xiàn)程中定時(shí)器的使用

多線(xiàn)程中定時(shí)器的使用

作者: 時(shí)間:2016-11-24 來(lái)源:網(wǎng)絡(luò ) 收藏
不管是在進(jìn)程還是線(xiàn)程,很多時(shí)候我們都會(huì )使用一些定時(shí)器之類(lèi)的功能,這里就定時(shí)器在多線(xiàn)程的使用說(shuō)一下。首先在linux編程中定時(shí)器函數有alarm()和setitimer(),alarm()可以提供一個(gè)基于秒的定時(shí)功能,而setitimer可以提供一個(gè)基于微妙的定時(shí)功能。 alarm()原型:
#i nclude
unsigned int alarm(unsigned int seconds);
這個(gè)函數在使用上很簡(jiǎn)單,第一次調用這個(gè)函數的時(shí)候是設置定時(shí)器的初值,下一次調用是重新設置這個(gè)值,并會(huì )返回上一次定時(shí)的剩余時(shí)間。
setitimer()原型:
#i nclude
int setitimer(int which, const struct itimerval *value,
struct itimerval *ovalue);
這個(gè)函數使用起來(lái)稍微有點(diǎn)說(shuō)法,首先是第一個(gè)參數which的值,這個(gè)參數設置timer的計時(shí)策略,which有三種狀態(tài)分別是:
ITIMER_REAL:使用系統時(shí)間來(lái)計數,時(shí)間為0時(shí)發(fā)出SIGALRM信號,這種定時(shí)能夠得到一個(gè)精準的定時(shí),當然這個(gè)定時(shí)是相對的,因為到了微秒級別我們的處理器本身就不夠精確。
ITIMER_VIRTUAL:使用進(jìn)程時(shí)間也就是進(jìn)程分配到的時(shí)間片的時(shí)間來(lái)計數,時(shí)間為0是發(fā)出SIGVTALRM信號,這種定時(shí)顯然不夠準確,因為系統給進(jìn)程分配時(shí)間片不由我們控制。
ITIMER_PROF:上面兩種情況都能夠觸發(fā)
第二個(gè)參數參數value涉及到兩個(gè)結構體:
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};

struct timeval {
long tv_sec;
long tv_usec;
};
在結構體itimerval中it_value是定時(shí)器當前的值,it_interval是當it_value的為0后重新填充的值。而timeval結構體中的兩個(gè)變量就簡(jiǎn)單了一個(gè)是秒一個(gè)是微秒。
上面是這兩個(gè)定時(shí)函數的說(shuō)明,這個(gè)函數使用本不是很難,可以說(shuō)是很簡(jiǎn)單,但是碰到具體的應用的時(shí)候可能就遇到問(wèn)題了,在多進(jìn)程編程中使用一般不會(huì )碰到什么問(wèn)題,這里說(shuō)的這些問(wèn)題主要體現在多線(xiàn)程編程中。比如下面這個(gè)程序
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude

void sig_handler(int signo)
{
alarm(2);
printf("alarm signal");
}

void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid;
int retval;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

while(1)
{
printf("main thread");
sleep(10);
}
return 0;
}
這個(gè)程序的理想結果是:
main thread
alarm signal
alarm signal
alarm signal
alarm signal
alarm signal
main thread
可事實(shí)上并不是這樣的,它的結果是:
main pthread
alarm signal
main pthread
alarm signal
main pthread
為什么會(huì )出現這種情況呢?是因為發(fā)送給工作線(xiàn)程的信號中斷的主線(xiàn)程的sleep,并且這個(gè)中情況只影響主線(xiàn)程而不會(huì )影響到其他的工作線(xiàn)程。我們怎么才能解決這種問(wèn)題呢,最簡(jiǎn)單的方法是修改這個(gè)程序,修改這個(gè)線(xiàn)程主線(xiàn)程使用alarm,工作線(xiàn)程使用sleep。這樣就能夠達到我們的要求,但是有時(shí)候有不能簡(jiǎn)單的這樣操作。所以我們就需要進(jìn)一步的修改我們的程序。在這里我第一個(gè)想到的是使用signal(SIGALRM, SIG_IGN),可是這個(gè)是設置整個(gè)進(jìn)程對這個(gè)信號的響應方式,經(jīng)過(guò)測試也確實(shí)不能完成我期望的功能,那么怎么辦呢?有這樣一個(gè)函數pthread_sigmask,線(xiàn)程中的信號屏蔽,函數的原型及相關(guān)函數為:
#i nclude
int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset);
函數中第一個(gè)參數how有三個(gè)值SIG_BLOCK、SIG_SETMASK和SIG_UNBLOCK這里我們是用第二個(gè)值SIG_SETMASK
int sigemptyset(sigset_t *set);
int sigaddset(sigset_t *set, int signum);
然后我們改造我們的程序為:
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude

void sig_handler(int signo)
{
alarm(2);
printf("alarm signal");
}

void *pthread_func()
{
alarm(2);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid, tid_1;
int retval;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);

while(1)
{
printf("main pthread");
sleep(10);
}
return 0;
}
這個(gè)時(shí)候我們就能夠看到我們想要的結果了。
這里再附一個(gè)setitimer的使用范例
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude

struct itimerval timerval;
void sig_handler(int signo)
{
printf("alarm signal");
}


void *pthread_func()
{

setitimer(ITIMER_REAL, &timerval, NULL);
while(1)
{
pause();
}
}

int main(int argc, char **argv)
{
pthread_t tid;
int retval;
timerval.it_interval.tv_sec = 2;
timerval.it_interval.tv_usec = 0;
timerval.it_value.tv_sec = 2;
timerval.it_value.tv_usec = 0;

signal(SIGALRM, sig_handler);

if((retval = pthread_create(&tid, NULL, pthread_func, NULL)) < 0)
{
perror("pthread_create");
exit(-1);
}

sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGALRM);
pthread_sigmask(SIG_SETMASK,&sigset,NULL);

while(1)
{
printf("main thread");
sleep(5);
}




return 0;

}



關(guān)鍵詞: 多線(xiàn)程定時(shí)

評論


技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>