C主循环没有100%cpu

时间:2009-08-03 14:10:47

标签: c loops main

#include <stdio.h>

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

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

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

11 个答案:

答案 0 :(得分:16)

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

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

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

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

答案 1 :(得分:11)

您有多种选择:

  1. 使用sleep()强制进程定期挂起并允许其他进程使用CPU
  2. 以较低优先级运行 - 这将导致操作系统分配较少的CPU时间
  3. 使用互斥锁或其他同步对象来检测工作何时可用 - 这将使进程不会消耗任何CPU时间,除非它实际上正在工作
  4. 如果你的工作速度超过你的工作速度 - 你可能仍然需要使用某种睡眠/优先级模型来避免完全消耗CPU。
  5. 选项#2在平台/操作系统中立方式下可能很棘手。最好的办法是启动流程并在运行时环境中更改其优先级。

答案 2 :(得分:5)

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

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

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

答案 3 :(得分:3)

你究竟要检查什么?

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

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

答案 4 :(得分:2)

如果我理解正确,你在评论中说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);

答案 5 :(得分:1)

使用

睡眠(int milliSeconds)

答案 6 :(得分:1)

Sleep(0);就足够了我猜

答案 7 :(得分:0)

使用yield()。

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

睡眠(0);