0

考虑以下正在运行循环的示例程序;

int main()
{

  for (int i = 0; i<= 300; ++i) {

  }

}

非常基本,现在假设我想打印出i每秒的值:

cout << "i= " << i << "\n";

像下面这样的简单循环可能就足够了,其中“elaspedTime”是一个虚构的整数,包含程序运行的秒数,由操作系统神奇地更新:

int lastTime = 0;
while (true) {
  if (elapsedTime > lastTime) { // Another second has passed
    cout << "i= " << "\n";
    lastTime = elapsedTime;
  }
}

这里的最终目标是提供如下输出(假设循环恰好每秒运行 100 次,因为它位于旧的、缓慢的 CPU 上):

$ ./myprog
i= 100
i= 200
i= 300

这些都是简单的函数和例程,尽管如此,我认为没有办法在通常只有一个main()函数的“经典”c++ 程序中执行这样的操作。尽管很简单,但这是我需要学习多线程的关键吗?或者,是否可以调用函数main()而不等待它们的返回,但没有被调用的函数“占用”线程?

4

3 回答 3

3

如果您希望两个函数在同一时间彼此独立地运行,则需要使用线程。您提供的示例不需要使用线程来完成您所说的想要完成的事情,但是根据您的评论,我认为您的问题有点不清楚。

多线程是 C++03 标准中没有提到的东西。最新的 C++11 标准对它有一些支持,但它不是全部,全部。多线程的实际实现方式是特定于平台的。WinTel 机器以一种方式进行,Linux/Intel 机器以另一种方式进行。编写多线程代码的两种主要方法是:

  1. 使用特定于平台的设施。
  2. 使用跨平台线程库。

刚开始时,这些天我建议从跨平台库开始,这样您就可以了解许多大图概念,而不会被特定于平台的特性所困扰。一个这样的库是Boost.Thread

编辑

鉴于您是多线程编程的新手,我觉得我应该警告您:您正在蒙着眼罩跳进一个深兔子洞。多线程编程有点像国际象棋——您可以相当快地学习很多基本语法和系统调用,但是正确地进行多线程编程需要大量的学习和实践。正确完成多线程编程是程序员将面临的最困难的事情之一。

另外,请特别注意下面@CrazyEddie 的评论:

一旦你从“功能”切换到“任务”,尽管故事发生了变化。根据任务的不同,很有可能一次完成许多任务。由于像 OP 这样的事件循环通常大部分时间都在休眠,因此线程通常仅用于方便而不是性能或必要性。我敢肯定你知道这一点,但 OP 可能不知道。OP 需要查找“异步处理”并权衡使用线程与非阻塞操作和事件循环的优缺点。

于 2012-05-09T15:19:03.897 回答
1

这样做有什么问题?无需多任务处理。

int lastTime = 0;
while (true) {
  if (std::time() > lastTime) { // Another second has passed
    cout << "i= " << i << "\n";
    // potentially expensive code goes here, which updates "i"
    lastTime = std::time();
  }
}
于 2012-05-09T15:07:54.830 回答
0

我很好奇你想解决什么问题。“想知道一秒钟内完成了多少次迭代”从何而来?我问的原因是因为您将使用顶部讨论的单线程方法(检查时钟-增量-检查时钟-增量...检查时钟-打印)或多线程方法得到答案,他们两者都受到引入线程运行的开销和不确定性的影响。我的意思是:在这两种情况下,你都必须执行一堆额外的东西——单线程情况下的时钟()调用和多线程情况下的线程同步。两者都会影响您的程序在一秒钟内完成的迭代总数(数量会更小),因此您将得到不正确的结果。此外还有' s 操作系统谁的线程调度程序是您的线程何时运行以及何时休眠等待下一个可用时间片的决定者。量子约为 20-30 毫秒,因此在时间间隔检查期间产生的错误很容易(可能平均而言)只有百分之几。

保存开始时间会不会更容易更自然,然后做所有需要做的迭代来处理所有数据(做所有工作),然后再次取时间戳并将迭代总数除以时间间隔。或者是否有特定于您正在解决的问题的问题,这种方法不起作用?

于 2012-05-10T19:03:31.963 回答