简体   繁体   English

C ++ while循环,usleep()/ sleep()如何不使用90%的CPU? (Ubuntu 12.04)

[英]C++ While loop, usleep()/sleep() how not to use 90% of CPU? (Ubuntu 12.04)

Suppose I have C++ code such as 假设我有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

The program will run fine and does what its supposed to do but it will use up 90%+ of my cpu. 该程序将运行良好,并做它应该做的,但它将使用我的CPU的90%以上。

It was suggested to me to use usleep() in my while loop ever 100ms or so since I really only care about doing stuff every 500ms anyway. 有人建议我在我的while循环中使用usleep()大约100ms左右,因为我真的只关心每隔500毫秒做一次东西。 That way, it hog the CPU when its not needed. 这样,它就会在不需要时占用CPU。

So I added it to my while loop like so 所以我把它添加到我的while循环中

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

It compiles fine, but when I run it, the program will hang right at usleep and never return. 它编译得很好,但是当我运行它时,程序将挂在我们的睡眠状态,永远不会返回。 I read somewhere that before calling usleep, one needs to flush all buffers, so I flushed all file streams and couts etc etc. Still no luck. 我在某个地方读过,在调用usleep之前,需要刷新所有缓冲区,所以我刷新所有文件流和couts等等。仍然没有运气。

I've searched for 2 days for a solution. 我已经搜索了2天的解决方案。 I've used sleep() too, with no luck. 我也用过sleep(),没有运气。

I found a few alternatives but they seem complicated and will add a lot of code to my program that I dont really fully understand which will complicate it and make it messy, plus it might not work. 我找到了一些替代方案,但它们似乎很复杂,并且会为我的程序添加大量代码,我真的完全不明白哪些会使它复杂化并使其变得混乱,而且它可能无法正常工作。

I never really put too much thought in my while() loops before because most of the programs I wrote were for microcontrollers or FPGAs which is no problem to hog the processor. 之前我的while()循环中从未真正考虑太多因为我编写的大多数程序都是针对微控制器或FPGA的,这对于处理器来说是没有问题的。

If anyone can help.... any resources, links,books? 如果有人可以帮助....任何资源,链接,书籍? Thanks. 谢谢。

Your approach somewhat comes from the wrong end. 你的方法有点来自错误的结局。 A program should consume 90-100% CPU as long as it has something useful to do (and it should block otherwise, consuming zero CPU). 程序应该消耗90-100%的CPU,只要它有一些有用的东西(否则它应该阻塞,消耗零CPU)。
Sleeping in between will cause execution being longer for no good reason, and consume more energy than just doing the work as fast as possible (at 100% CPU) and then completely blocking until more work is available or until some other significant thing (eg half a second has passed, if that matters for you) happens. 在两者之间睡觉将导致执行时间更长,没有充分的理由,并且消耗更多的能量,而不是仅仅尽可能快地完成工作(在100%CPU),然后完全阻塞,直到有更多的工作可用或直到其他重要的事情(例如一半)如果这对你很重要,那么第二个过去了。

With that in mind, structure your program in a way conceptually like: 考虑到这一点,以一种概念性的方式构建您的程序:

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

Also, do not sleep during execution, but use timers (eg setitimer ) to do something at regular intervals. 此外,不要在执行期间睡觉,而是使用计时器(例如setitimer )定期执行某些操作。 Not only will this be more efficient, but also a lot more precise and reliable. 这不仅效率更高,而且更精确可靠。

How exactly you implement this depends on how portable you want your software to be. 您如何实现这一点取决于您希望软件的可移植性。 Under Ubuntu/Linux, you can for example use APIs such as epoll_wait with eventfd rather than writing a signal handler for the timer. Ubuntu下/ Linux的,比如,你可以使用API,例如epoll_waiteventfd而不是写定时器的信号处理程序。

This code works as expected for me (running on OSX though). 这段代码对我来说是预期的(尽管在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;
  }

There is a logical issue or maybe you're making multiple counters? 有一个逻辑问题,或者你正在制作多个计数器? Since you said you've done microcontrollers, I assume you're trying to use clock-cycles as a method of counting while calling the system timers? 既然你说你已经完成了微控制器,我假设你在调用系统定时器时尝试使用时钟周期作为计数方法? Also, what has me questioning is if you're recommended to use usleep(x), why are you using double for millisecond? 另外,让我质疑的是,如果你被推荐使用usleep(x),为什么你使用double为毫秒? usleep(1) is 1 microsecond == 1000 milliseconds. usleep(1)是1微秒== 1000毫秒。 The sleep(x) is a counter per x second, so the system will suspend it's current task for x amount of seconds. 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;
}

If you wanted to use 500ms then replace usleep(SECOND) with usleep(500*MILLISECOND). 如果你想使用500毫秒,那么用usleep(500 * MILLISECOND)替换usleep(SECOND)。 I suggest you use a debugger and step through your code to see what's happening. 我建议您使用调试器并逐步执行代码以查看发生了什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM