C主循环没有100%cpu

#include  int main() { while(!DONE) { /* check for stuff */ } return 0; } 

上面的代码示例使用100%cpu,直到DONE为真。 如何实现一个循环的程序,只在DONE时终止,但不使用100%cpu? 现代语言使用类似App.ProcessMessages之类的东西来让操作系统暂时控制,然后返回循环。

我是C的新手,显然……使用最新的GCC,linux和windows(便携式解决方案会很棒!)

这取决于你想在这个循环中做什么。

如果你在循环内等待(即如果按下了{do something}那么你的机制会浪费系统资源而不给予任何回报。更快的处理器只会产生更多的空闲循环。这可以通过等待事件来解决不只是睡觉,而是优选地,触发可以完成某些有意义的事件的事件。例如,文件操作(stdin也是文件)将是一种可移植的机制。这将在数据可用之前让位给其他应用程序。当你变得更具体时它可能被要求潜入信号量或通常依赖于操作系统的信号。抽象层可以解决这个问题。

如果你正在做一些有用的事情(即处理大量数据),那么100%cpu加载只意味着处理器以最有效的方式使用。 您可以依赖操作系统让位于其他可能更高优先级的任务。

使用像sleep这样的函数会降低cpu的使用率,但你的应用程序会变慢。 它需要在可接受的性能和CPU负载之间进行权衡。 最大执行速度将由sleep参数定义,而不再由cpu速度定义。 此外,如果电力是一个问题(即电池寿命),那么这将需要CPU唤醒(睡眠期结束),没有工作要做; 即系统资源的不同浪费。

你有几个选择:

  1. 使用sleep()强制进程定期挂起并允许其他进程使用CPU
  2. 以较低优先级运行 – 这将导致操作系统分配较少的CPU时间
  3. 使用互斥锁或其他同步对象来检测工作何时可用 – 这将使进程不会消耗任何CPU时间,除非它实际上正在工作
  4. 如果您的工作速度超过了处理速度 – 您可能仍需要使用某种睡眠/优先级模型来避免完全消耗CPU。

选项#2在平台/操作系统中立方式下可能很棘手。 最好的办法是启动流程并在运行时环境中更改其优先级。

您的两个选项是轮询,以及某种事件通知。

轮询是最容易编程的 – 基本上你每次通过循环都会让你的线程rest一会儿。 这会将处理器释放到其他任务中。 缺点是你的“检查东西”代码会有延迟 – 所以如果你睡了一秒钟,它可能会在你的代码检测到这个条件之前达到一秒钟。 这里的代码很容易移植。

另一个选择是等待POSIX条件,或Windows事件或类似的东西。 这个代码不仅会被更改,而且“你正在检查的东西”将需要触发标志来说明它已完成。 这可能是一个不太可移植的代码,尽管可能有一些库可以抽象出平台。 但是你会立即得到事件的结果,并且不会浪费处理器时间来检查那些不存在的东西。

你究竟要检查什么?

如果您正在检查由硬件或其他进程更改的易失性内容,请在循环中调用sleep

如果要等待文件描述符或网络套接字描述符,则需要在循环中使用selectpoll来等待描述符准备好使用数据。

如果我理解正确,你在评论中说DONE可以从其他线程改变。 如果是这样,条件变量是有意义的。 使用pthreads,可以做到:

在等待的线程中:

 pthread_mutex_lock(&mutex); while (!DONE) { pthread_cond_wait(&cond, &mutex); } pthread_mutex_unlock(&mutex); 

在其他线程中,当DONE更改时:

 pthread_mutex_lock(&mutex); DONE = 1; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); 

使用

睡眠(int milliSeconds)

Sleep(0); 我猜是够的

使用yield ()。

如果我正确猜测(我不知道它),相当于App.ProcessMessages正在阻止IO。 由于我不知道任何使用轮询的多任务操作系统上的C实现,任何标准C IO都应该是安全的。

在Windows上,您可以使用在windows.h上定义的Sleep(int毫秒)。

睡眠(0); 足够