正确的方法来暂停和恢复std :: thread

Gam*_*ads 7 c++ lambda c++11 stdthread c++14

std::thread在我的C++代码中使用一个不断轮询一些数据并将其添加到缓冲区.我使用a C++ lambda来启动这样的线程:

StartMyThread() {

    thread_running = true;
    the_thread = std::thread { [this] {
        while(thread_running) {
          GetData();
        }
    }};
}
Run Code Online (Sandbox Code Playgroud)

thread_runningatomic<bool>在类头中声明的.这是我的GetData功能:

GetData() {
    //Some heavy logic which needs to be executed in a worker thread
}
Run Code Online (Sandbox Code Playgroud)

接下来我还有一个StopMyThread函数,我将其设置thread_running为false,以便它退出while中的while循环lambda block.

StopMyThread() {
  thread_running = false;
  the_thread.join();
}
Run Code Online (Sandbox Code Playgroud)

它运作良好.线程启动和停止而不会崩溃.

此C++代码用于iOS,Android,OS X和Windows.我的应用程序UI有一个按钮,要求我按下按钮启动和停止线程; 这个按钮可以在某些场合经常使用.我可以在停止或启动线程时看到UI中的瞬间延迟.

我的问题是: 在C++中,这是经常启动/停止线程的正确方法吗?我认为通过这种逻辑,我每次都在创建一个新的线程.据我所知,创建一个新线程会使操作系统分配大量新资源,这些资源可能会耗费时间.我认为这是我正在做的错误.我怎么能避免这个?

如何在整个应用程序生命周期中不重复分配新线程的情况下使用相同的线程,并在需要时播放/暂停?

use*_*108 6

这是使用条件变量的经典示例.您等待互斥锁并在满足某个条件时通知线程; 这样您就不需要在需要时分配新线程,但如果您希望节省内存,这并不总是一件好事.另一种选择是在需要数据时向另一个协同程序产生协程,这可以说是更漂亮的.您需要自己实现协同程序,或使用现成的库,例如boost.coroutine.

::std::condition_variable cv_;
::std::mutex m_;
bool data_is_ready_{};

StartMyThread()
{
  ::std::thread([this]
    {
      for (;;)
      {
        ::std::unique_lock<decltype(m_)> l(m_);
        cv.wait(l, [this]{ return data_is_ready_; });

        // do your stuff, m_ is locked
        data_is_ready_ = false;
      }
    }
  ).detach();
}
Run Code Online (Sandbox Code Playgroud)

通知:

{
  ::std::unique_lock<decltype(m_)> l(m_);

  data_is_ready_ = true;
}

cv_.notify_one();
Run Code Online (Sandbox Code Playgroud)

因为在通知之前释放锁通常更快,反之亦然.

  • 挑剔的.为什么要完全限定`std`命名空间?除非你做了一些令人讨厌和错误的事情,否则它是丑陋无用的. (5认同)