mirror of
https://github.com/sogou/workflow.git
synced 2026-02-08 01:33:17 +08:00
63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
# 关于定时器
|
||
|
||
定时器的作用是不占线程的等待一个确定时间,同样通过callback来通知定时器到期。
|
||
|
||
# 定时器的创建
|
||
|
||
同样是在WFTaskFactory类里的方法:
|
||
~~~cpp
|
||
using timer_callback_t = std::function<void (WFTimerTask *)>;
|
||
|
||
class WFTaskFactory
|
||
{
|
||
...
|
||
static WFTimerTask *create_timer_task(unsigned int microseconds,
|
||
timer_callback_t callback);
|
||
static WFTimerTask *create_timer_task(time_t seconds, long nanoseconds,
|
||
timer_callback_t callback);
|
||
};
|
||
~~~
|
||
目前我们提供两个创建定时器的工厂函数。第一个函数接收一个unsigned int型参,时间单位为微秒。
|
||
如果用户需要更长时间或更高精度的定时,可以使用第二个函数接口。接口接受两个参数,分别为秒和纳秒。实际上,这个接口也具备更高的性能。
|
||
定时器任务里同样有user_data域可以用来传递一些用户数据。启动方法和接入任务流的方法与其它任务没有区别。
|
||
|
||
# 定时器的一个高级特征
|
||
|
||
在[关于程序退出](./about-exit.md)里讲到,main函数结束或exit()被调用的时候,所有任务必须里运行到callback,并且没有新的任务被调起。
|
||
这时就可能出现一个问题,定时器的定时周期可以非常长,并且不能主动打断(打断定时器的功能正在研发)。如果等定时器到期,程序退出需要很长时间。
|
||
而实现上,程序退出是可以打断定时器,让定时器回到callback的。如果定时器被程序退出打断,get_state()会得到一个WFT_STATE_ABORTED状态。
|
||
当然如果定时器被程序退出打断,则不能再调起新的任务。
|
||
以下这个程序,每间隔一秒抓取一个一个http页面。当所有url抓完毕,程序直接退出,不用等待timer回到callback,退出不会有延迟。
|
||
~~~cpp
|
||
bool program_terminate = false;
|
||
|
||
void timer_callback(WFTimerTask *timer)
|
||
{
|
||
mutex.lock();
|
||
if (!program_terminate)
|
||
{
|
||
WFHttpTask *task;
|
||
if (urls_to_fetch > 0)
|
||
{
|
||
task = WFTaskFactory::create_http_task(...);
|
||
series_of(timer)->push_back(task);
|
||
}
|
||
|
||
series_of(timer)->push_back(WFTaskFactory::create_timer_task(1, 0, timer_callback));
|
||
}
|
||
mutex.unlock();
|
||
}
|
||
|
||
...
|
||
int main()
|
||
{
|
||
....
|
||
/* all urls done */
|
||
mutex.lock();
|
||
program_terminate = true;
|
||
mutex.unlock();
|
||
return 0;
|
||
}
|
||
~~~
|
||
以上程序,timer_callback必须在锁里判断program_terminate条件,否则可能在程序已经结束的情况下又调起新任务。
|