为while循环创建超时的最简洁方法是什么?

时间:2010-01-25 22:00:08

标签: c++ c windows algorithm winapi

Windows API / C / C ++

1. ....  
2. ....
3. ....    
4.    while (flag1 != flag2)
5.    {
6.      SleepEx(100,FALSE);   
        //waiting for flags to be equal (flags are set from another thread).
7.    }
8. .....
9. .....  

如果标志在7秒后不相等,我想继续第8行。

感谢任何帮助。感谢。

7 个答案:

答案 0 :(得分:10)

如果您正在等待设置特定标志或达到时间,则更清洁的解决方案可能是使用自动/手动重置事件。这些设计用于线程之间的信令条件,并且具有在其上设计的非常丰富的API。例如,您可以使用WaitForMultipleObjects API,它采用显式超时值。

答案 1 :(得分:6)

不要轮询要更改的标志。即使在循环期间出现睡眠或产量,这也只会浪费CPU周期。

相反,获取设置标志的线程会通知您它们已被更改,可能使用event。你对事件的等待会超时,你可以通过调整来等待7秒钟。

例如:

Thread1:

 flag1 = foo;
 SetEvent(hEvent);


 Thread2:

 DWORD timeOutTotal = 7000;  // 7 second timeout to start.
 while (flag1 != flag2 && timeOutTotal > 0)
 {
     // Wait for flags to change
     DWORD start = GetTickCount();

     WaitForSingleObject(hEvent, timeOutTotal);

     DWORD end = GetTickCount();

    // Don't let timeOutTotal accidently dip below 0.
    if ((end - start) > timeOutTotal)
    {
        timeOutTotal = 0;
    }
    else
    {
       timeOutTotal -= (end - start);
    }

 }

答案 2 :(得分:3)

您可以使用WinAPI中的QueryPerformanceCounter。在开始之前检查它,并查询是否已经过了一段时间。但是,这是一个高分辨率计时器。对于较低分辨率,请使用GetTickCount(毫秒)。

全部取决于您是在积极等待(做某事)还是被动地等待外部过程。如果是后者,则使用Sleep的以下代码将更容易:

int count = 0;
while ( flag1 != flag2 && count < 700 )
{
   Sleep( 10 ); // wait 10ms
   ++count;
}

如果您不使用Sleep(或Yield)并且您的应用程序不断检查某个条件,那么您将使应用程序运行的CPU膨胀。

如果你广泛使用WinAPI,你应该尝试更原生的解决方案,阅读关于WinAPI的Synchronization Functions

答案 3 :(得分:3)

你没有提到如果标志相等会发生什么。

另外,如果您只是在没有内存障碍的情况下测试它们,那么您无法保证看到其他线程所做的任何写入。

您最好的选择是使用一个事件,并使用WaitForSingleObject函数,超时7000毫秒。

答案 4 :(得分:2)

确保你在那里做sleep()yield(),否则你会吃掉所有整个CPU(或核心)。

答案 5 :(得分:1)

我会说“检查时间,如果七秒后没有发生任何事情,那么就打破循环。

答案 6 :(得分:0)

如果您的应用程序执行某些网络工作,请查看POSIX select()调用,尤其是超时功能!