21
#include <stdio.h>

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

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

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

4

11 回答 11

16

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

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

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

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

于 2009-08-03T14:26:27.823 回答
12

你有几个选择:

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

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

于 2009-08-03T14:16:08.373 回答
7

您的两个选择是轮询和某种事件通知。

轮询将是最容易编程的——基本上你的线程在每次通过循环时都会休眠一小会儿。这会将处理器释放到其他任务。缺点是你的“检查东西”代码会有延迟——所以如果你睡了一秒钟,你的代码可能需要一秒钟才能检测到这种情况。您在此处的代码将很容易移植。

另一种选择是等待 POSIX 条件或 Windows 事件或类似事件。不仅会更改此代码,而且“您正在检查的内容”将需要触发标志以表示已完成。尽管可能有库可以抽象出平台,但这将是可移植性较差的代码。但是您会立即获得事件的结果,并且不会浪费处理器时间检查不存在的东西。

于 2009-08-03T14:15:38.733 回答
3

你到底在检查什么?

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

如果您正在等待文件描述符或网络套接字描述符,您将希望在循环中使用selectpoll等待描述符准备好数据以供使用。

于 2009-08-03T14:14:23.040 回答
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);
于 2009-08-03T14:47:26.963 回答
2

Sleep(0);我想就足够了

于 2013-07-09T08:03:31.977 回答
1

采用

睡眠(int 毫秒)

于 2009-08-03T14:12:57.783 回答
0

使用产量()。

于 2009-08-03T14:14:42.383 回答
0

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

于 2009-08-03T14:15:36.860 回答
0

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

于 2009-08-03T14:20:09.573 回答
0

睡眠(0);足够

于 2009-10-24T14:56:32.340 回答