假设我有像这样的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循环中每100毫秒左右使用usleep(),因为我真的只在乎每500毫秒做一次。这样,当不需要的时候,它就会占用CPU。
所以我把它添加到while循环中,就像一样
while(minutes <=timelimit)
{
//...do stuff
if(milliseconds>500)
{
//...do stuff
//...every half second
} //end if
usleep(100000);
} //end while
它编译得很好,但当我运行它时,程序会挂在usleep上,永远不会返回。我在某个地方读到,在调用usleep之前,需要刷新所有缓冲区,所以我刷新了所有文件流和couts等。仍然没有运气。
我找了两天的解决方案。我也用过sleep(),运气不好。
我找到了一些替代方案,但它们看起来很复杂,会给我的程序添加很多我不完全理解的代码,这会使它复杂化,变得混乱,而且可能不起作用。
我以前从来没有在while()循环中考虑过太多,因为我写的大多数程序都是针对微控制器或FPGA的,这对占用处理器来说没有问题。
如果有人能帮忙。。。。有资源、链接、书籍吗?谢谢
您的方法有些错误。程序应该消耗90-100%的CPU,只要它有有用的事情要做(否则它应该阻塞,消耗零CPU)
介于两者之间的睡眠会导致执行时间毫无理由地延长,消耗更多的能量,而不仅仅是以尽可能快的速度(以100%的CPU)完成工作,然后完全阻塞,直到有更多的工作可用,或者直到发生其他重要的事情(例如,如果这对你来说很重要的话,半秒钟已经过去)。
考虑到这一点,以一种概念上类似于的方式来构建你的程序
while(blocking_call() != exit_condition)
{
while(have_work)
do_work();
}
此外,在执行过程中不要休眠,而是使用计时器(例如setitimer
)定期执行某些操作。这样不仅效率更高,而且更加精确可靠。
具体实现方式取决于您希望软件的可移植性。例如,在Ubuntu/Linux下,您可以使用epoll_wait
和eventfd
等API,而不是为计时器编写信号处理程序。
这段代码对我来说是预期的(不过是在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;
}
是否存在逻辑问题,或者您正在制作多个计数器?既然你说你已经做了微控制器,我想你是在尝试使用时钟周期作为一种计数方法,同时调用系统计时器吗?此外,让我质疑的是,如果建议您使用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(500*MILLISECOND)代替usleep。我建议您使用调试器并逐步查看代码中发生了什么。