在C++中每隔x秒运行一个函数

3
我正在尝试用C++构建一个新闻聚合阅读器,因此需要程序间歇性地检查新的新闻源。但是,用户仍然需要能够与程序交互,所以我似乎一直找到的建议是让系统等待,这对我来说不起作用。有人可以提供更好的解决方案吗?比如在后台运行的计时器之类的东西?
谢谢, Charles

3
仅使用后台计时器是不够的;在尝试读取信息流时,你的程序有可能因为某些不在你控制范围内的原因而超时,在这种情况下,你的程序也会被卡住。为了正确解决这两个问题,你需要进入多线程的神奇世界... - Jon
你是在使用某种GUI工具包,还是一个简单的命令行程序?如果你正在使用GUI工具包,那么很可能有一个事件循环可以附加一个定时器用于回调。 - luke
正确的方法取决于操作系统和用户界面工具包。 - Winston Ewert
6个回答

3

您可以创建一个休眠指定时间段的线程,这是与操作系统无关的。或者,如果您在Windows中进行编程,可以设置计时器以定期发送超时事件。计时器的使用取决于您的部署平台。


谢谢,我会看一下的。我知道这很主观,但是仅仅让一个线程暂停,这样做似乎有点混乱,还是说这就是标准做法? - wyatt
线程暂停实际上非常有益 - 操作系统可以自行决定:“好的,他在接下来的x秒内不会使用它;我可以在此期间安排其他任务。”另一种选择是运行一个不断检查“时间是否到了”的循环。在这种情况下,操作系统将继续分配时间给“暂停”的线程;因此更加低效。 - Smashery
2
请注意,如果您只有1秒钟的固定暂停时间,并且工作需要0.5秒钟才能完成,那么您最终将每1.5秒运行一次。您可能需要考虑工作所需的时间。 - AshleysBrain

2

你可以使用SIGALRM来每隔n秒获得中断。这不需要一个单独的线程。你的主线程将进入一个信号处理程序。

void sigtime(int signo)
{
    signal(SIGALRM, sigtime);
}
....
signal(SIGALRM, sigtime);
itimerval itm;
itm.it_interval.tv_sec=0;
itm.it_value.tv_sec = 0;
itm.it_interval.tv_usec = 200000;
itm.it_value.tv_usec = 200000;
setitimer(ITIMER_REAL,&itm,0);

当然,这假设您正在使用类Unix的系统上


+1 和 http://www.opengroup.org/onlinepubs/009695399/functions/getitimer.html 参见 alarm http://www.opengroup.org/onlinepubs/009695399/functions/alarm.html,后者放弃了结构以使用简单的整数秒。 - Potatoswatter

2
你需要使用线程。在后台有一个线程负责计时,前台有一个线程与用户交互。然后在线程之间建立一些共享内存区域,后台线程可以通过调用你的特定函数来修改它,前台线程可以查看它。也许可以研究一下boost线程库:http://www.boost.org/doc/libs/1_43_0/doc/html/thread.html

1

我也想制作一个程序,每隔x分钟或小时执行一次函数,我找到了许多示例,但要实现这个功能,必须包含并下载一个库,对我来说不太方便,所以我自己制作了一个,虽然不是很合乎逻辑,但它确实可以工作,你可以在下面看到它。

 #include <stdlib.h>
 #include <iostream>
 #include <time.h>
 using namespace std;

 struct tm *addtime(struct tm *tm2)
 {
      time_t t = time(0);   // get time now
     struct tm * tm1  = localtime( & t );
     cout << " Time begin : " << tm1->tm_hour << " : " << tm1->tm_min <<endl;
     struct tm * aux = (struct tm*)malloc(sizeof (struct tm));

     aux->tm_sec = tm1->tm_sec + tm2->tm_sec;
     aux->tm_min = tm1->tm_min + tm2->tm_min + (aux->tm_sec / 60) ;
     aux->tm_hour = tm1->tm_hour + tm2->tm_hour +  (aux->tm_min / 60);
     aux->tm_min %= 60;
     aux->tm_sec %= 60;
     return (aux);

 }
 bool verif_time(struct tm *tm1)
 {

     time_t t = time(0);   // get time now
     struct tm * now = localtime( & t );
     if (tm1->tm_hour == now->tm_hour && tm1->tm_min == now->tm_min)
         return true;
     else
         return false;

 }

  int main()
  {
     struct tm * after = (struct tm*)malloc(sizeof (struct tm));

     after->tm_sec = 0; // here you can modify difference between now time and time when you want to execute function 
     after->tm_min = 1;
     after->tm_hour = 0;

     after = addtime(after);
     cout << " After time" << after->tm_hour << ':' << after->tm_min<<endl;
     while (true)
     {
         if (verif_time(after))
         {
             cout << "Hello " << after->tm_hour << " : " << after->tm_min<<endl; //here you can include your function 

             after->tm_sec = 0;
             after->tm_min = 1;
             after->tm_hour = 0; // here also 

             after = addtime(after);
             cout << " After time" << after->tm_hour << ':' << after->tm_min<<endl;


         }
     }

  }

1

将UI和Feed阅读器分为独立的线程。如果用户执行需要立即更新Feed的操作,请中断Feed线程。


0

在我看来,这听起来像是观察者设计模式的候选人:

http://en.wikipedia.org/wiki/Observer_pattern#C.2B.2B

创建一个线程,它会间歇性地检查源,并调用你的主类/具体观察者类中的handleEvent方法。这样,你的主类就不会处于等待状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接