4

假设我有 C++ 代码,例如

#include "myheaderfiles.h"
//..some stuff
//...some more stuff
int main()
{
   double milliseconds;
   int seconds;
   int minutes;
   int timelimit=2;
   ...
   ...
   //...code here that increments 
   //.....milliseconds,seconds, and minutes

   while(minutes <=timelimit)
   {
      //...do stuff
      if(milliseconds>500)
      {
         //...do stuff 
         //...every half second
      } //end if
   } //end while
}//end main

该程序将运行良好并完成它应该做的事情,但它会占用我 90% 以上的 cpu。

有人建议我在我的 while 循环中使用 usleep() 每 100 毫秒左右,因为我真的只关心每 500 毫秒做一次事情。这样,它会在不需要时占用 CPU。

所以我像这样将它添加到我的while循环中

   while(minutes <=timelimit)
   {
      //...do stuff
      if(milliseconds>500)
      {
         //...do stuff 
         //...every half second
      } //end if
      usleep(100000);
   } //end while

它编译得很好,但是当我运行它时,程序会在睡眠时挂起并且永远不会返回。我在某处读到,在调用 usleep 之前,需要刷新所有缓冲区,所以我刷新了所有文件流和 couts 等。仍然没有运气。

我已经搜索了 2 天的解决方案。我也使用过 sleep() ,但没有运气。

我找到了一些替代方案,但它们看起来很复杂,并且会在我的程序中添加很多我不完全理解的代码,这会使它复杂化并使它变得混乱,而且它可能无法正常工作。

之前我从未真正在 while() 循环中考虑过太多,因为我编写的大多数程序都是针对微控制器或 FPGA 的,这对占用处理器来说是没有问题的。

如果有人可以提供帮助....任何资源,链接,书籍?谢谢。

4

3 回答 3

2

你的方法有点来自错误的结局。只要有有用的事情要做,程序就应该消耗 90-100% 的 CPU(否则它应该阻塞,消耗零 CPU)。
在两者之间休眠会导致执行时间更长,并且消耗更多的能量,而不是尽可能快地完成工作(在 100% CPU 下)然后完全阻塞直到有更多工作可用或直到一些其他重要的事情(例如一半一秒钟过去了,如果这对你很重要)发生了。

考虑到这一点,在概念上以如下方式构建您的程序:

while(blocking_call() != exit_condition)
{
    while(have_work)
        do_work();
}

此外,在执行期间不要休眠,而是使用计时器(例如setitimer)定期执行某些操作。这不仅会更有效,而且会更加精确和可靠。

您如何实现这一点取决于您希望软件的可移植性。在 Ubuntu/Linux 下,您可以使用诸如epoll_waitwith之类的 API,eventfd而不是为计时器编写信号处理程序。

于 2014-04-22T07:36:21.960 回答
0

这段代码对我来说按预期工作(虽然在 OSX 上运行)。

  #include <unistd.h>
  #include <iostream> 

  int main() {
    std::cout << "hello" << std::endl;

    int i = 0;
    while(i < 10) {
      ++i;
      usleep(100000);
      std::cout << "i = " << i << std::endl;                                                                                                                                        
    }
    std::cout << "bye" << std::endl;
    return 0;
  }
于 2014-04-22T06:36:30.863 回答
0

有一个逻辑问题,或者您正在制作多个计数器?既然您说您已经完成了微控制器,我假设您在调用系统计时器时尝试使用时钟周期作为计数方法?另外,我要问的是,如果建议您使用 usleep(x),为什么要使用 double 毫秒?usleep(1) 是 1 微秒 == 1000 毫秒。sleep(x) 是每 x 秒的计数器,因此系统会将其当前任务挂起 x 秒。

#include <iostream>
#include <unistd.h>

using namespace std;

#define MILLISECOND 1000
#define SECOND 1000*MILLISECOND

int main(int argc, char *argv[]){
    int time = 20;
    int sec_counter = 0;
    do{     
        cout<<sec_counter<<" second"<<endl;
        usleep(SECOND);
        sec_counter++;
    } while(sec_counter<time+1);
    return 0;
}

如果您想使用 500 毫秒,请将 usleep(SECOND) 替换为 usleep(500*MILLISECOND)。我建议您使用调试器并单步执行您的代码以查看发生了什么。

于 2014-04-22T08:10:36.527 回答