是循环的方式。
11 个解决方案
#1
sleep
alarm
都可以吧
alarm
都可以吧
#2
linux下的器定时作用的函数很多,比如常用的sleep()函数,这里不再过多说这个。主要说的关于定时器精度和循环定时器的应用,尤其是在多线程应用过程中所要注意的定时器问题。
1. alarm()和signal()函数
alarm()函数在自己规定的时间到来时,向系统发送一个名为SIGALRM的信号,如果你想在自己规定的时间后运行一个函数,那么就是用 signal(int ,void*)函数,他的第一个参数是接收到的信号,比如说是SIGALRM,第二个参数是要运行的函数的地址,这样就达到了在某个时间后运行一个函数的目的。但是在多线程的程序里会出现差错,可以试一试如果发送一个信号后,有多个线程signal会出现什么差错。
2. setitimer()精确定时
此函数可以达到微妙级别的定时(但要考路到内核HZ,不一定能达到),我们可以看一下他的参数
setitmer(int which, const struct itimerval *value, struct itimerval *ovalue)
第一个参数是信号类型具体可以查到,而itimerval结构体,就是定义触发时间的结构体,它包含两个参数 :一个是下次定时的时间取值(分为秒和微妙)一个是本次定时的设置,具体结构可以man 到。最后一个参数可以设置为NULL,此函数虽然达到了精确定时,但是在多线程里好像只能三个吧,(多指教),并且会产生与上面说的同一类问题如果你用 signal接受的话。
3. select()函数
此函数使用在文件操作里面的,当然socket编程不会少了它,我在使用计时器时看到了网上使用它的一些例子,但是立即就放弃了,因为感觉很难似的,在操作文件编程时也没着重研究,过了几天学习socket并发编程时,又一次见到了她,这是才发现基本上是很简单的,尤其是用在计时器上,(教训啊)这里简单介绍一下相关计时器的编程,socket以后再说。
好了,开始了:
int select(int n, fd_set *readfds, fe_set *writefds, fd_set *exceptfds, struct timeval *timeout );
看上去很难吧,O(∩_∩)O~,现在就看计时器了所以就把中间三个参数设成NULL,不用管,第一个参数设置成 0,最后一个就够体和上面的差不多:
struct timeval{
long tv_sec; // seconds
long tv_usec; // microseconds
}
可以精确到微妙,可以了吧,设置上时间,比如 struct timeval time = { 1,30 },此时设置的是一秒30微妙,此时变成了:
select( 0, NULL, NULL,NULL,time),简单了吧,一个一秒30微妙的定时器了,每到时间了就触发了,好像没信号,也没什么特殊要求(比如不能超过三个),按道理来说是应该每隔一定时间就触发一次,但是在伯克利系统中(什么是伯克利啊?——自己查吧)他不是自动触发的要设置信号(用sigaction() 函数)这个不用管,好了,如果你就想定时一次,有一个就行了,但是你想每隔time一次 呢,好办 while(1){....select(....).....}无限循环不就可以了。
综合分析::
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的,还有一个是精确到纳秒的,但是由于系统内核的原因好像不是这么精确,微妙就不错了。
setitmer()可以循环计时,其他不行,如果不是在多线程里没什么问题。
那么在多线程里会出什么问题呢:在多线程里信号时共享的,当然进程资源也是共享的,所以一个alarm(),setitimer()发信号都能收到,如果好几个线程都接手signal()那么就不能确定哪一个线程收到了信号,所以有随机性,那么怎样在多线程环境里设置定时器呢?这里说的是设置一个定时器,到时间了运行设定好的函数,这个问题下一篇来讲,当然系统有相应函数库,我说的是自己编出来了。
1. alarm()和signal()函数
alarm()函数在自己规定的时间到来时,向系统发送一个名为SIGALRM的信号,如果你想在自己规定的时间后运行一个函数,那么就是用 signal(int ,void*)函数,他的第一个参数是接收到的信号,比如说是SIGALRM,第二个参数是要运行的函数的地址,这样就达到了在某个时间后运行一个函数的目的。但是在多线程的程序里会出现差错,可以试一试如果发送一个信号后,有多个线程signal会出现什么差错。
2. setitimer()精确定时
此函数可以达到微妙级别的定时(但要考路到内核HZ,不一定能达到),我们可以看一下他的参数
setitmer(int which, const struct itimerval *value, struct itimerval *ovalue)
第一个参数是信号类型具体可以查到,而itimerval结构体,就是定义触发时间的结构体,它包含两个参数 :一个是下次定时的时间取值(分为秒和微妙)一个是本次定时的设置,具体结构可以man 到。最后一个参数可以设置为NULL,此函数虽然达到了精确定时,但是在多线程里好像只能三个吧,(多指教),并且会产生与上面说的同一类问题如果你用 signal接受的话。
3. select()函数
此函数使用在文件操作里面的,当然socket编程不会少了它,我在使用计时器时看到了网上使用它的一些例子,但是立即就放弃了,因为感觉很难似的,在操作文件编程时也没着重研究,过了几天学习socket并发编程时,又一次见到了她,这是才发现基本上是很简单的,尤其是用在计时器上,(教训啊)这里简单介绍一下相关计时器的编程,socket以后再说。
好了,开始了:
int select(int n, fd_set *readfds, fe_set *writefds, fd_set *exceptfds, struct timeval *timeout );
看上去很难吧,O(∩_∩)O~,现在就看计时器了所以就把中间三个参数设成NULL,不用管,第一个参数设置成 0,最后一个就够体和上面的差不多:
struct timeval{
long tv_sec; // seconds
long tv_usec; // microseconds
}
可以精确到微妙,可以了吧,设置上时间,比如 struct timeval time = { 1,30 },此时设置的是一秒30微妙,此时变成了:
select( 0, NULL, NULL,NULL,time),简单了吧,一个一秒30微妙的定时器了,每到时间了就触发了,好像没信号,也没什么特殊要求(比如不能超过三个),按道理来说是应该每隔一定时间就触发一次,但是在伯克利系统中(什么是伯克利啊?——自己查吧)他不是自动触发的要设置信号(用sigaction() 函数)这个不用管,好了,如果你就想定时一次,有一个就行了,但是你想每隔time一次 呢,好办 while(1){....select(....).....}无限循环不就可以了。
综合分析::
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的,还有一个是精确到纳秒的,但是由于系统内核的原因好像不是这么精确,微妙就不错了。
setitmer()可以循环计时,其他不行,如果不是在多线程里没什么问题。
那么在多线程里会出什么问题呢:在多线程里信号时共享的,当然进程资源也是共享的,所以一个alarm(),setitimer()发信号都能收到,如果好几个线程都接手signal()那么就不能确定哪一个线程收到了信号,所以有随机性,那么怎样在多线程环境里设置定时器呢?这里说的是设置一个定时器,到时间了运行设定好的函数,这个问题下一篇来讲,当然系统有相应函数库,我说的是自己编出来了。
#3
第一种方法:
void startTimer()
{
struct itimerval tick;
int res;
memset(&tick, 0, sizeof(tick));
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = MINTIMERINTERVAL*1000;
signal(SIGALRM, timerFunc);
res = setitimer(ITIMER_REAL, &tick, NULL);
if (res) {
DEBUG_ERR("Set timer failed!!\n");
}
}
void timerFunc()
{
//要实现的内容
}
第二种方法:
用一个线程来实现这种方法,
void startTimer()
{
struct itimerval tick;
int res;
memset(&tick, 0, sizeof(tick));
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = MINTIMERINTERVAL*1000;
signal(SIGALRM, timerFunc);
res = setitimer(ITIMER_REAL, &tick, NULL);
if (res) {
DEBUG_ERR("Set timer failed!!\n");
}
}
void timerFunc()
{
//要实现的内容
}
第二种方法:
用一个线程来实现这种方法,
#4
while(1)
{
sleep(1);///睡1秒,linux下。
}
{
sleep(1);///睡1秒,linux下。
}
#5
2楼说的很详细了。
#6
如果不要求很精确的话,用 alarm() 和 signal() 就够了
代码:
/*
* Example for alarm.
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
/* Do something */
printf("alarm!\n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
/* Do someting */
while(1) pause();
}
代码:
/*
* Example for alarm.
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
/* Do something */
printf("alarm!\n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
/* Do someting */
while(1) pause();
}
#7
顶
#8
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的
#9
ls的挖坟呀
#10
一天之后的话用crontab命令
#11
libevent
#1
sleep
alarm
都可以吧
alarm
都可以吧
#2
linux下的器定时作用的函数很多,比如常用的sleep()函数,这里不再过多说这个。主要说的关于定时器精度和循环定时器的应用,尤其是在多线程应用过程中所要注意的定时器问题。
1. alarm()和signal()函数
alarm()函数在自己规定的时间到来时,向系统发送一个名为SIGALRM的信号,如果你想在自己规定的时间后运行一个函数,那么就是用 signal(int ,void*)函数,他的第一个参数是接收到的信号,比如说是SIGALRM,第二个参数是要运行的函数的地址,这样就达到了在某个时间后运行一个函数的目的。但是在多线程的程序里会出现差错,可以试一试如果发送一个信号后,有多个线程signal会出现什么差错。
2. setitimer()精确定时
此函数可以达到微妙级别的定时(但要考路到内核HZ,不一定能达到),我们可以看一下他的参数
setitmer(int which, const struct itimerval *value, struct itimerval *ovalue)
第一个参数是信号类型具体可以查到,而itimerval结构体,就是定义触发时间的结构体,它包含两个参数 :一个是下次定时的时间取值(分为秒和微妙)一个是本次定时的设置,具体结构可以man 到。最后一个参数可以设置为NULL,此函数虽然达到了精确定时,但是在多线程里好像只能三个吧,(多指教),并且会产生与上面说的同一类问题如果你用 signal接受的话。
3. select()函数
此函数使用在文件操作里面的,当然socket编程不会少了它,我在使用计时器时看到了网上使用它的一些例子,但是立即就放弃了,因为感觉很难似的,在操作文件编程时也没着重研究,过了几天学习socket并发编程时,又一次见到了她,这是才发现基本上是很简单的,尤其是用在计时器上,(教训啊)这里简单介绍一下相关计时器的编程,socket以后再说。
好了,开始了:
int select(int n, fd_set *readfds, fe_set *writefds, fd_set *exceptfds, struct timeval *timeout );
看上去很难吧,O(∩_∩)O~,现在就看计时器了所以就把中间三个参数设成NULL,不用管,第一个参数设置成 0,最后一个就够体和上面的差不多:
struct timeval{
long tv_sec; // seconds
long tv_usec; // microseconds
}
可以精确到微妙,可以了吧,设置上时间,比如 struct timeval time = { 1,30 },此时设置的是一秒30微妙,此时变成了:
select( 0, NULL, NULL,NULL,time),简单了吧,一个一秒30微妙的定时器了,每到时间了就触发了,好像没信号,也没什么特殊要求(比如不能超过三个),按道理来说是应该每隔一定时间就触发一次,但是在伯克利系统中(什么是伯克利啊?——自己查吧)他不是自动触发的要设置信号(用sigaction() 函数)这个不用管,好了,如果你就想定时一次,有一个就行了,但是你想每隔time一次 呢,好办 while(1){....select(....).....}无限循环不就可以了。
综合分析::
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的,还有一个是精确到纳秒的,但是由于系统内核的原因好像不是这么精确,微妙就不错了。
setitmer()可以循环计时,其他不行,如果不是在多线程里没什么问题。
那么在多线程里会出什么问题呢:在多线程里信号时共享的,当然进程资源也是共享的,所以一个alarm(),setitimer()发信号都能收到,如果好几个线程都接手signal()那么就不能确定哪一个线程收到了信号,所以有随机性,那么怎样在多线程环境里设置定时器呢?这里说的是设置一个定时器,到时间了运行设定好的函数,这个问题下一篇来讲,当然系统有相应函数库,我说的是自己编出来了。
1. alarm()和signal()函数
alarm()函数在自己规定的时间到来时,向系统发送一个名为SIGALRM的信号,如果你想在自己规定的时间后运行一个函数,那么就是用 signal(int ,void*)函数,他的第一个参数是接收到的信号,比如说是SIGALRM,第二个参数是要运行的函数的地址,这样就达到了在某个时间后运行一个函数的目的。但是在多线程的程序里会出现差错,可以试一试如果发送一个信号后,有多个线程signal会出现什么差错。
2. setitimer()精确定时
此函数可以达到微妙级别的定时(但要考路到内核HZ,不一定能达到),我们可以看一下他的参数
setitmer(int which, const struct itimerval *value, struct itimerval *ovalue)
第一个参数是信号类型具体可以查到,而itimerval结构体,就是定义触发时间的结构体,它包含两个参数 :一个是下次定时的时间取值(分为秒和微妙)一个是本次定时的设置,具体结构可以man 到。最后一个参数可以设置为NULL,此函数虽然达到了精确定时,但是在多线程里好像只能三个吧,(多指教),并且会产生与上面说的同一类问题如果你用 signal接受的话。
3. select()函数
此函数使用在文件操作里面的,当然socket编程不会少了它,我在使用计时器时看到了网上使用它的一些例子,但是立即就放弃了,因为感觉很难似的,在操作文件编程时也没着重研究,过了几天学习socket并发编程时,又一次见到了她,这是才发现基本上是很简单的,尤其是用在计时器上,(教训啊)这里简单介绍一下相关计时器的编程,socket以后再说。
好了,开始了:
int select(int n, fd_set *readfds, fe_set *writefds, fd_set *exceptfds, struct timeval *timeout );
看上去很难吧,O(∩_∩)O~,现在就看计时器了所以就把中间三个参数设成NULL,不用管,第一个参数设置成 0,最后一个就够体和上面的差不多:
struct timeval{
long tv_sec; // seconds
long tv_usec; // microseconds
}
可以精确到微妙,可以了吧,设置上时间,比如 struct timeval time = { 1,30 },此时设置的是一秒30微妙,此时变成了:
select( 0, NULL, NULL,NULL,time),简单了吧,一个一秒30微妙的定时器了,每到时间了就触发了,好像没信号,也没什么特殊要求(比如不能超过三个),按道理来说是应该每隔一定时间就触发一次,但是在伯克利系统中(什么是伯克利啊?——自己查吧)他不是自动触发的要设置信号(用sigaction() 函数)这个不用管,好了,如果你就想定时一次,有一个就行了,但是你想每隔time一次 呢,好办 while(1){....select(....).....}无限循环不就可以了。
综合分析::
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的,还有一个是精确到纳秒的,但是由于系统内核的原因好像不是这么精确,微妙就不错了。
setitmer()可以循环计时,其他不行,如果不是在多线程里没什么问题。
那么在多线程里会出什么问题呢:在多线程里信号时共享的,当然进程资源也是共享的,所以一个alarm(),setitimer()发信号都能收到,如果好几个线程都接手signal()那么就不能确定哪一个线程收到了信号,所以有随机性,那么怎样在多线程环境里设置定时器呢?这里说的是设置一个定时器,到时间了运行设定好的函数,这个问题下一篇来讲,当然系统有相应函数库,我说的是自己编出来了。
#3
第一种方法:
void startTimer()
{
struct itimerval tick;
int res;
memset(&tick, 0, sizeof(tick));
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = MINTIMERINTERVAL*1000;
signal(SIGALRM, timerFunc);
res = setitimer(ITIMER_REAL, &tick, NULL);
if (res) {
DEBUG_ERR("Set timer failed!!\n");
}
}
void timerFunc()
{
//要实现的内容
}
第二种方法:
用一个线程来实现这种方法,
void startTimer()
{
struct itimerval tick;
int res;
memset(&tick, 0, sizeof(tick));
tick.it_value.tv_sec = 1; // sec
tick.it_value.tv_usec = 0; // micro sec.
tick.it_interval.tv_sec = 0;
tick.it_interval.tv_usec = MINTIMERINTERVAL*1000;
signal(SIGALRM, timerFunc);
res = setitimer(ITIMER_REAL, &tick, NULL);
if (res) {
DEBUG_ERR("Set timer failed!!\n");
}
}
void timerFunc()
{
//要实现的内容
}
第二种方法:
用一个线程来实现这种方法,
#4
while(1)
{
sleep(1);///睡1秒,linux下。
}
{
sleep(1);///睡1秒,linux下。
}
#5
2楼说的很详细了。
#6
如果不要求很精确的话,用 alarm() 和 signal() 就够了
代码:
/*
* Example for alarm.
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
/* Do something */
printf("alarm!\n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
/* Do someting */
while(1) pause();
}
代码:
/*
* Example for alarm.
*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
/* Do something */
printf("alarm!\n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
/* Do someting */
while(1) pause();
}
#7
顶
#8
sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的
#9
ls的挖坟呀
#10
一天之后的话用crontab命令
#11
libevent