【问题标题】:measure elapsed time in c++ multithreaded program在 C++ 多线程程序中测量经过的时间
【发布时间】:2023-03-12 01:35:01
【问题描述】:

我有一个用于 C++ 跳棋游戏的 AI Minimax 代码。在这里,主程序调用我在一个新线程中编写的函数,同时它会休眠 5 秒,然后返回到主程序

int flag = 0 ;
void execute(){
    hThread = ( HANDLE ) _beginthread( myfunction ) ;
    sleep( 5000 );

    if(flag == 1) // Do some work 
}


Outputval myfunction(...) {

   clock_t start = clock() ;
   while( double(clock() - start)/CLOCKS_PER_SEC < 4 ) {   //CLOCKS_PER_SEC = 1000

      //DO SOME WORK

   }
   flag = 1;
   return somevalue ;

}

我的问题是,虽然在我的函数中完成的工作大约需要 3-4 秒,但每次迭代后计算的经过时间是 0-1 秒的时间。因此,即使 4 秒过去且未设置标志,myfunction 中的循环也会继续运行 我也使用了 time() 函数 - 它给出了同样的问题。

【问题讨论】:

  • 没有 () 的 void 执行 工作吗? CLOCKS_PER_SEC 定义为什么?使用 time_t 以秒为单位返回时间会更容易吗?
  • 我觉得你的设计不是很好。不能保证 myfunction() 将在主线程的睡眠终止之前完成其工作。无论如何,你想要达到什么目的?产生一个新线程来执行工作是否有真正的理由?如果您的主线程正忙于做其他事情,那将是有道理的,但就目前而言,除了等待之外,它并没有真正做任何事情。此外,您应该尝试使用信号量或互斥体而不是标志,因为它们更安全,并且超时可能是等待函数中固有的。
  • 这就是我使用循环的原因。我必须在 myfunction() 中确保它在主线程上的睡眠终止之前返回。执行函数 execute 我无法更改,因为它来自其他团队,必须按原样使用。我唯一可以修改的是 myfunction()。
  • @user3289221 很抱歉,如果不更改 execute() 函数,则无法绝对保证您在 5 秒超时之前完成执行。这是一个示例:假设 myfunction() 中循环的第一次迭代耗时 3.5 秒。当检查 while 时,它​​仍然小于 4,因此再次执行循环。这次只需要 2.5(耶!)秒。你头脑中的一个快速计算将表明这总共是 6 秒,因此比主线程等待的 5 秒多。 (令人惊讶的是,当主线程检查时,标志可能仍然是 1)
  • 谢谢。我刚刚得出了和你一样的结论。因此,我使用(经过的时间)

标签: c++ multithreading time


【解决方案1】:

不是答案,而是“警告”:

假设你的变量 flag 是全局的并且在两个线程中都是可见的。由于至少一个访问不是原子的 (C++11) 或 flag 不是 volatile (C++03),因此您的代码包含“数据竞争”,并且这将触发“未定义的行为”。未定义的行为为编译器打开了广泛的优化机会:

编译器会优化你的代码如下:

开始于:

int flag = 0 ;
void execute{
    hThread = ( HANDLE ) _beginthread( myfunction ) ;
    sleep( 5000 );

    if(flag == 1) // Do some work 
}

它最终可能会创建此代码:

constexpr int flag = 0 ;
void execute{
    hThread = ( HANDLE ) _beginthread( myfunction ) ;
    sleep( 5000 );

    if(0) {}// Never do anything
}

您的代码还有其他问题。我建议彻底重新设计。

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多