【问题标题】:How to stop an std::thread from running, without terminating the program如何在不终止程序的情况下停止 std::thread 运行
【发布时间】:2014-05-31 19:01:53
【问题描述】:

我正在尝试向C++11 学习std::threads 来制作线程系统。

我想知道是否有一种方法可以在不终止整个程序的情况下阻止线程运行(不是休眠,而是真正破坏线程等等)。

我知道std::join 存在,但这会强制线程等待所有线程返回。

还有其他方法可以解决这个问题吗? (例如,无需阻塞线程即可创建ThreadPool 类?)

【问题讨论】:

  • 开箱即用没有这种可能性。但您可以尝试 boost::thread 或编写自己的此功能实现
  • std::thread 几乎知道线程实现必须知道的所有内容:1.) 创建线程 2.) 加入它。你不需要其他任何东西。不幸的是,优雅地“杀死线程”实际上是要求线程退出并在它退出时加入它。有时实现它是平台相关的,但对于事件/条件,您通常可以独立地实现它。

标签: c++ multithreading c++11 stdthread


【解决方案1】:

也许这个 thread_pool 会帮助你:

#include <boost/thread.hpp>
#include <boost/phoenix.hpp>
#include <boost/optional.hpp>

using namespace boost;
using namespace boost::phoenix::arg_names;

boost::atomic_size_t counter(0ul);

class thread_pool
{
  private:
      mutex mx;
      condition_variable cv;

      typedef function<void()> job_t;
      std::deque<job_t> _queue;

      thread_group pool;

      boost::atomic_bool shutdown;
      static void worker_thread(thread_pool& q)
      {
          while (optional<job_t> job = q.dequeue())
              (*job)();
      }

  public:
      thread_pool() : shutdown(false) {
          for (unsigned i = 0; i < boost::thread::hardware_concurrency(); ++i)
              pool.create_thread(bind(worker_thread, ref(*this)));
      }

      void enqueue(job_t job) 
      {
          lock_guard<mutex> lk(mx);
          _queue.push_back(job);

          cv.notify_one();
      }

      optional<job_t> dequeue() 
      {
          unique_lock<mutex> lk(mx);
          namespace phx = boost::phoenix;

          cv.wait(lk, phx::ref(shutdown) || !phx::empty(phx::ref(_queue)));

          if (_queue.empty())
              return none;

          job_t job = _queue.front();
          _queue.pop_front();

          return job;
      }

      ~thread_pool()
      {
          shutdown = true;
          {
              lock_guard<mutex> lk(mx);
              cv.notify_all();
          }

          pool.join_all();
      }
};

使用示例:live On Coliru

【讨论】:

  • 很好地使用while ( 声明 )
【解决方案2】:

C++ std::thread 类实际上只是一个最小接口,位于一些更完整的实现定义的线程包之上。因此,它只定义了少量功能——创建新线程、detachjoin。差不多就是这样——没有标准的方法来管理、调度、停止/启动/终止线程或做很多其他事情。

有一个native_handle 方法,它返回一个实现定义的类型,它可能可以用来做你想做的事情,具体取决于实现。

【讨论】:

  • 我不太明白。 std::thread 具有底层线程实现所具有的所有功能(以不能便携使用或无论如何都不安全使用的东西为模。各个“线程包”中的所有重要其他位也都在那里(条件变量(又名事件)、(递归)互斥锁(又名关键部分)、(唯一)锁助手等。
【解决方案3】:

没有办法以非合作方式阻止线程使用标准 C++ 运行。这并不意味着不可能,但您可能需要回到系统原生句柄。

对于符合标准的方式,您可以使用同步原语(例如std::atomic&lt;bool&gt;)从外部设置终止标志并在线程内读取它。但它仍然必须是自己完成的线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2020-03-06
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多