【问题标题】:thread and Sleep线程和睡眠
【发布时间】:2018-08-09 19:16:24
【问题描述】:

我正在尝试了解多线程的工作原理。

我有这个代码:

#include <iostream>
#include <thread>
#include <chrono>

void function1() {

   std::cout << "Hi I'm the function 1" << std::endl;
   std::this_thread::sleep_for(std::chrono::seconds(1));
   std::cout << "Hi I'm the function 1 after sleeping" << std::endl;

}

void function2() {

  std::cout << "Hi I'm the function 2" << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(5));
  std::cout << "Hi I'm the function 2 after sleeping" << std::endl;

}

int main()
{

  while(true) {

     std::thread t1(function1);
     std::thread t2(function2);

     t1.join();
     t2.join();

  }

  system("pause");
  return 0;

}

问题是当我运行它时,它会停止等待std::this_thread::sleep_for(std::chrono::seconds(5));,并且不会在下一个循环中显示来自std::thread t1(function1); 的下一个Hi I'm the function 1,直到睡眠线程结束。

1) 你知道为什么吗?

2) 我希望 main 继续循环,不要等到 t2 完成(function2 中的 sleep_for() 设置为 5 秒)

【问题讨论】:

  • “你知道为什么吗?”因为您对其进行了编程以做到这一点。您启动两个线程,然后等到 both 完成。然后重新开始。如果您希望一个连续循环并且等待另一个,则需要对 that 进行编程。
  • 我怀疑你真的打算在你的线程内部有循环,但是如果你没有告诉我们,你很难知道你想做什么。
  • 是的,我想休眠线程,在其他程序中我想使用它,例如在游戏中,我需要在每次按键之间设置延迟,但同时我需要知道是否键被按下 GetAsyncKeyState()。

标签: c++ multithreading performance sleep thread-sleep


【解决方案1】:

1) 这是我的输出,看起来符合我的预期:

Hi I'm the function 1
Hi I'm the function 2
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 1
Hi I'm the function 2
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1
Hi I'm the function 1 after sleeping
Hi I'm the function 2 after sleeping
Hi I'm the function 2
Hi I'm the function 1

2) 你的最佳表现是什么意思???? sleep_for() 适用于任何地方,而 Sleep 是特定于 Windows 的......

我建议尽可能使用 std 库,放置睡眠的位置取决于您的上下文...

【讨论】:

  • 不,我不想这样,因为 function2 中的 sleep_for() 设置为 5 秒,我希望 main 继续循环,不要等到 t2 完成。
【解决方案2】:

这就是您的代码的作用:

  • 开始线程 1
    • 输出消息
    • 等待 1 秒
    • 输出另一条消息
  • 启动线程 2
    • 输出消息
    • 等待 5 秒
    • 输出另一条消息
  • 等待两个线程完成
    • (这大约需要 5 秒)
  • 无限重复

你说过这不是你的本意。

我认为,相反,您打算让每个线程的“重复”内部,以便它们继续独立且无限期地滴答作响,如下所示:

#include <iostream>
#include <thread>
#include <chrono>

void function1() {
   while (true) {
      std::cout << "Hi I'm the function 1" << std::endl;
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "Hi I'm the function 1 after sleeping" << std::endl;
   }
}

void function2() {
  while (true) {
     std::cout << "Hi I'm the function 2" << std::endl;
     std::this_thread::sleep_for(std::chrono::seconds(5));
     std::cout << "Hi I'm the function 2 after sleeping" << std::endl;
   }
}

int main()
{
   std::thread t1(function1);
   std::thread t2(function2);

   t1.join();
   t2.join();
}

现在您的代码会这样做:

  • 开始线程 1
    • 输出消息
    • 等待 1 秒
    • 输出另一条消息
    • 无限重复
  • 启动线程 2
    • 输出消息
    • 等待 5 秒
    • 输出另一条消息
    • 无限重复
  • 等待两个线程完成
    • (尽管两者都不会!)

现在每个线程都独立旋转,任何一个都不会“阻塞”另一个。

【讨论】:

  • 好的,这是正确的答案,所以我应该总是在线程内使用循环,而不是在 main() 中?
  • @EduardoG:不是“总是”——当你想让你的电脑做这件事时,你应该这样做。
  • 你能解释一下这两个线程是如何从while loop退出的吗?
  • @AbhijitPritam:不会。我在解释中说明了这一点。
  • 您始终应该提供完美的答案。这个程序永远不会结束,你必须杀死它。你的解释是不够的,它实际上是一个糟糕的答案。第二个连接语句将永远不会执行。你笑我对多线程一无所知,现在问问你自己。
【解决方案3】:

当你加入一个线程时,它会完成它的执行并退出。因此,当您加入线程时 t1.join();和 t2.join();,只有当第一个 join 语句完成时,第二个语句才会执行。因此,在您的情况下,要连续增加线程并并行执行,您必须分离线程,如下所示:-

int i = 0;
while(true) {

 std::thread t1(function1);
 std::thread t2(function2);

 t1.detach();
 t2.detach();

//also break your infinite loop here
if( ++i < 4)
   break;
}

【讨论】:

  • 这将创建如此多的线程,您的头脑(和计算机)会爆炸。
  • 确实如此。他必须控制他的无限循环。更正了我的答案。
  • 第一次迭代后停止不是死循环。
  • @LightnessRacesinOrbit,感谢您的建议。我已经通过答案更正了。 :-)
  • @LightnessRacesinOrbit,这取决于他想如何使用他的代码。尊重你的感觉。将其减少为 3。:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
相关资源
最近更新 更多