不管是在进程仍是线程,许多时分咱们都会运用一些守时器之类的功用,这儿就守时器在多线程的运用说一下。首先在linux编程中守时器函数有alarm()和setitimer(),alarm()可以供给一个根据秒的守时功用,而setitimer可以供给一个根据奇妙的守时功用。
unsigned int alarm(unsigned int seconds);
这个函数在运用上很简略,第一次调用这个函数的时分是设置守时器的初值,下一次调用是从头设置这个值,并会回来上一次守时的剩余时刻。
#i nclude
int setitimer(int which, const struct itimerval *value,
这个函数运用起来略微有点说法,首先是第一个参数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结构体中的两个变量就简略了一个是秒一个是微秒。
上面是这两个守时函数的阐明,这个函数运用本不是很难,可以说是很简略,但是碰到详细的运用的时分或许就遇到问题了,在多进程编程中运用一般不会碰到什么问题,这儿说的这些问题首要体现在多线程编程中。比方下面这个程序
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
void sig_handler(int signo)
{
}
void *pthread_func()
{
}
int main(int argc, char **argv)
{
}
这个程序的抱负成果是:
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,线程中的信号屏蔽,函数的原型及相关函数为:
#i nclude
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);
int sigaddset(sigset_t *set, int signum);
然后咱们改造咱们的程序为:
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
void sig_handler(int signo)
{
}
void *pthread_func()
{
}
int main(int argc, char **argv)
{
}
这个时分咱们就可以看到咱们想要的成果了。
这儿再附一个setitimer的运用典范
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
struct itimerval timerval;
void sig_handler(int signo)
{
}
void *pthread_func()
{
}
int main(int argc, char **argv)
{
}