std::thread 在 C++ 中未执行函数。

huangapple go评论116阅读模式
英文:

std::thread dosnt dosnt excute funtion c++

问题

这是您提供的代码的翻译部分:

  1. 我有这个简单的函数:
  2. class Timer {
  3. std::atomic<bool> active{true};
  4. public:
  5. void setInterval(auto function, int interval);
  6. void stop();
  7. };
  8. void Timer::setInterval(auto function, int interval) {
  9. active = true;
  10. std::thread t([=]() {
  11. while(active.load()) {
  12. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  13. if(!active.load()) return;
  14. function();
  15. }
  16. });
  17. t.detach();
  18. }
  19. void Timer::stop() {
  20. active = false;
  21. }
  22. 现在当我尝试运行它:
  23. int main()
  24. {
  25. printf("start\n");
  26. Timer* timer = new Timer();
  27. timer->setInterval([&]() {
  28. std::cout << "hello" << std::endl;
  29. }, 1000);
  30. return 0;
  31. };
  32. 仅从主类中打印开始,它从未到达setInterval函数内的function(); 它只是停止了应用程序,没有错误。
  33. 编译/链接命令:
  34. /usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main
英文:

i have this simple function :

  1. class Timer {
  2. std::atomic&lt;bool&gt; active{true};
  3. public:
  4. void setInterval(auto function, int interval);
  5. void stop();
  6. };
  7. void Timer::setInterval(auto function, int interval) {
  8. active = true;
  9. std::thread t([=]() {
  10. while(active.load()) {
  11. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  12. if(!active.load()) return;
  13. function();
  14. }
  15. });
  16. t.detach();
  17. }
  18. void Timer::stop() {
  19. active = false;
  20. }

Now when i try to run it :

  1. int main()
  2. {
  3. printf(&quot;start\n&quot;);
  4. Timer* timer = new Timer();
  5. timer-&gt;setInterval([&amp;]() {
  6. std::cout &lt;&lt; &quot;hello&quot; &lt;&lt; std::endl;
  7. },1000);
  8. return 0;
  9. };

Only the start printed from the main class , its never reach the function(); inside the
setInterval function its just stops the app with no error .

the compile/link command :

  1. /usr/bin/g++ -fdiagnostics-color=always -std=c++14 -pthread -g /home/vagrant/cpp/batch/main.cpp -o /home/vagrant/cpp/batch/main

答案1

得分: 2

这是正确使用线程对象来运行计时器的众多方法之一。

  1. #include <atomic>
  2. #include <thread>
  3. #include <chrono>
  4. #include <iostream>
  5. class Timer {
  6. private:
  7. std::atomic<bool> active = false;
  8. std::unique_ptr<std::thread> timer_thread;
  9. public:
  10. // 这个类需要一个析构函数。
  11. ~Timer()
  12. {
  13. stop();
  14. }
  15. // 这个函数名字有误导性,
  16. // void setInterval(auto function, int interval);
  17. //
  18. // 让我们将其重命名为它实际做的事情,还要尽量将函数参数放在最后,
  19. // 这样在使用lambda表达式调用时,代码更易读。
  20. //
  21. // 你不知道 'cb',调用者的可调用对象是可复制还是可移动的,所以应该使用完美
  22. // 转发,这仅在模板中( readily)可用。
  23. template <typename Fn>
  24. void start(int interval, Fn&& cb)
  25. {
  26. stop(); // 确保我们停止了。
  27. active = true;
  28. // 启动线程,回调对象的 forward<> 是重要的!
  29. timer_thread = std::make_unique<std::thread>(
  30. [this, ms = std::chrono::milliseconds(interval), cb = std::forward<Fn>(cb)]() {
  31. while (active) // 调用 atomic<>::load() 自动完成
  32. {
  33. std::this_thread::sleep_for(ms);
  34. if (active)
  35. cb();
  36. }
  37. });
  38. }
  39. // 这是我们终止线程并等待它退出的地方。
  40. void stop()
  41. {
  42. active = false;
  43. if (timer_thread)
  44. {
  45. timer_thread->join();
  46. timer_thread.reset();
  47. }
  48. }
  49. bool isRunning() const
  50. {
  51. return active;
  52. }
  53. };
  54. int main()
  55. {
  56. std::cout << "start\n";
  57. Timer timer; // 绝对没有必要将计时器放在堆上。
  58. int n = 4; // 一个简单的倒计时示例,直到1。
  59. timer.start(1000, [&]() {
  60. std::cout << "countdown: " << n << '\n';
  61. if (--n <= 0)
  62. timer.stop();
  63. });
  64. // 在退出程序之前,我们应该等待计时器停止。
  65. while (timer.isRunning()) {}
  66. return 0;
  67. };

请注意,上述代码是使用C++编写的,用于创建一个简单的计时器。如果您需要进一步的解释或有其他问题,请随时提出。

英文:

Here is one of the many ways of correctlty using a thread object to run your timer.

  1. #include &lt;atomic&gt;
  2. #include &lt;thread&gt;
  3. #include &lt;chrono&gt;
  4. #include &lt;iostream&gt;
  5. class Timer {
  6. private:
  7. std::atomic&lt;bool&gt; active = false;
  8. std::unique_ptr&lt;std::thread&gt; timer_thread;
  9. public:
  10. // this class needs a destructor.
  11. ~Timer()
  12. {
  13. stop();
  14. }
  15. // this function name is misleading,
  16. // void setInterval(auto function, int interval);
  17. //
  18. // let&#39;s rename it to what it does, also try to keep
  19. // the function argument last, this makes the code
  20. // more legible when calling with a lambda.
  21. //
  22. // you do not know if &#39;cb&#39;, the caller&#39;s callable object
  23. // is copyable or moveable, so you should use perfect
  24. // forwarding, that&#39;s only (readily) available from a
  25. // template.
  26. template &lt;typename Fn&gt;
  27. void start(int interval, Fn&amp;&amp; cb)
  28. {
  29. stop(); // make sure we&#39;re stopped.
  30. active = true;
  31. // start the thread, the forward&lt;&gt; of the callback object is
  32. // important!
  33. timer_thread = std::make_unique&lt;std::thread&gt;(
  34. [this, ms = std::chrono::milliseconds(interval), cb = std::forward&lt;Fn&gt;(cb)]() {
  35. while (active) // calls atomic&lt;&gt;::load() automatically
  36. {
  37. std::this_thread::sleep_for(ms);
  38. if (active)
  39. cb();
  40. }
  41. });
  42. }
  43. // this is where we kill the thread, and wait for it to exit.
  44. void stop()
  45. {
  46. active = false;
  47. if (timer_thread)
  48. {
  49. timer_thread-&gt;join();
  50. timer_thread.reset();
  51. }
  52. }
  53. bool isRunning() const
  54. {
  55. return active;
  56. }
  57. };
  58. int main()
  59. {
  60. std::cout &lt;&lt; &quot;start\n&quot;;
  61. Timer timer; // There&#39;s absolutely no need to place timer on the heap.
  62. int n = 4; // simple countdown to 1 for example.
  63. timer.start(1000, [&amp;]() {
  64. std::cout &lt;&lt; &quot;countdown: &quot; &lt;&lt; n &lt;&lt; &#39;\n&#39;;
  65. if (--n &lt;= 0)
  66. timer.stop();
  67. });
  68. // We should wait for the timer to stop, before exiting the program.
  69. while (timer.isRunning()) {}
  70. return 0;
  71. };

huangapple
  • 本文由 发表于 2023年1月9日 19:15:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/75056477.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定