如何解决通过一个线程运行多种功能
method1()
{
while(1)
{
some task;
sleep(900); //sleep for .9 second
}
}
method2()
{
some task;
}
AfxBeginThread(method1,NULL);
我想在method1内部每隔一分钟调用一次method2,而while循环每隔约1秒运行一次。我可以每1分钟从method1调用method2吗?如果是,如何?,如果否,如何每分钟调用method2而不创建另一个线程?
解决方法
一种方法是简单地使method1
定期轮询系统以查看是否经过了1分钟,例如:
method1()
{
auto start = ...; // GetTickCount/64(),std::chrono::steady_clock::now(),etc
while (not stopped)
{
some task;
Sleep(900); //sleep for .9 second
auto end = ...; // GetTickCount/64(),etc
if ((end-start) > 60000ms)
{
method2();
start = end;
}
}
}
另一种方法是让method1
改用waitable timer,设置为1分钟间隔,然后只要计时器过去,循环就可以调用method2
,例如:
method1()
{
HANDLE timer = CreateWaitableTimer(NULL,FALSE,NULL);
LARGE_INTEGER DueTime;
DueTime.QuadPart = -600000000; // due in 1 minute from now
SetWaitableTimer(timer,&DueTime,60000,NULL,FALSE); // 1 minute intervals after the DueTime passes
while (not stopped)
{
some task;
Sleep(900); //sleep for .9 second
if (WaitForSingleObject(timer,0) == WAIT_OBJECT_0) // has timer elapsed yet?
method2();
}
CancelWaitableTimer(timer);
CloseHandle(timer);
}
或者,等待计时器支持APC回调,例如:
void CallMethod2(LPVOID,DWORD,DWORD)
{
method2();
}
method1()
{
HANDLE timer = CreateWaitableTimer(NULL,&CallMethod2,FALSE); // 1 minute intervals after the DueTime passes
while (not stopped)
{
some task;
SleepEx(900,TRUE); //sleep for .9 second,call callback if timer elapsed
}
CancelWaitableTimer(timer);
CloseHandle(timer);
}
在两种情况下,您都可以扩展它以使用第二个等待计时器以0.9秒的间隔触发“某些任务”,然后在第一种情况下使用WaitForMultipleObjects()
循环,并使用第二个APC在第二种情况下回调,例如:
method1()
{
HANDLE timer1 = CreateWaitableTimer(NULL,NULL);
HANDLE timer2 = CreateWaitableTimer(NULL,NULL);
LARGE_INTEGER DueTime;
DueTime.QuadPart = -9000000; // due in 900ms from now
SetWaitableTimer(timer1,900,FALSE); // .9 second intervals after the DueTime passes
DueTime.QuadPart = -600000000; // due in 1 minute from now
SetWaitableTimer(timer2,FALSE); // 1 minute intervals after the DueTime passes
HANDLE h[] = {timer1,timer2};
while (not stopped)
{
switch (WaitForMultipleObjects(h,2,INFINITE))
{
case WAIT_OBJECT_0+0:
some task;
break;
case WAIT_OBJECT_0+1:
method2();
break;
}
}
CancelWaitableTimer(timer1);
CancelWaitableTimer(timer2);
CloseHandle(timer1);
CloseHandle(timer2);
}
void PerformSomeTask(LPVOID,DWORD)
{
some task;
}
void CallMethod2(LPVOID,DWORD)
{
method2();
}
method1()
{
HANDLE timer1 = CreateWaitableTimer(NULL,&PerformSomeTask,FALSE); // 1 minute intervals after the DueTime passes
while (not stopped)
{
SleepEx(INFINITE,TRUE); //sleep until an APC callback is called
}
CancelWaitableTimer(timer1);
CancelWaitableTimer(timer2);
CloseHandle(timer1);
CloseHandle(timer2);
}
或者,您可以改用线程池计时器:
VOID CALLBACK PerformSomeTask(PTP_CALLBACK_INSTANCE,PVOID,PTP_TIMER)
{
some task;
}
VOID CALLBACK CallMethod2(PTP_CALLBACK_INSTANCE,PTP_TIMER)
{
method2();
}
method1()
{
PTP_TIMER timer1 = CreateThreadpoolTimer(&PerformSomeTask,NULL);
PTP_TIMER timer2 = CreateThreadpoolTimer(&CallMethod2,NULL);
ULARGE_INTEGER DueTime;
FILETIME ft;
DueTime.QuadPart = -9000000; // due in 900ms from now
ft.dwLowDateTime = DueTime.LowPart;
ft.dwHighDateTime = DueTime.HighPart;
SetThreadpoolTimer(timer1,&ft,0); // .9 second intervals after the DueTime passes
DueTime.QuadPart = -600000000; // due in 1 minute from now
ft.dwLowDateTime = DueTime.LowPart;
ft.dwHighDateTime = DueTime.HighPart;
SetThreadpoolTimer(timer2,0); // 1 minute intervals after the DueTime passes
wait for stop condition ...
CloseThreadpoolTimer(timer1);
CloseThreadpoolTimer(timer2);
}
,
如果您的循环每秒大约运行一次迭代,那么您在循环的第60次迭代中所做的任何事情都会大约每分钟发生一次-我
是的,但是如何? -拉梅什(Ramesh)
int count = 0;
while (1) {
...
if (++count >= 60) {
count = 0;
method2();
}
}
精度非常重要,method2应该每天精确调用1440次。
不一样。在这种情况下,您应该遵循Remy Lebeau的建议:检查每次迭代的实际时间。如果已超过应调用method2()的时间,请对其进行调用并重新计算。
我不知道什么是C ++程序正确的函数调用。用伪代码:
some_time_type_t method2_due_at = time_now() + 60_seconds;
while (1) {
...
if (time_now() > method2_due_at) {
method2();
method2_due_at += 60_seconds;
}
}
即使循环每天不能精确执行86,400次迭代,您每天仍将获得1440 method2()
个调用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。