How to stop an std::thread from running, without terminating the program

前端 未结 3 1775
时光取名叫无心
时光取名叫无心 2020-12-17 05:44

I am trying to learn std::threads from C++11 to make a threading system.

I was wondering if there is a way to stop a thread from running (N

相关标签:
3条回答
  • 2020-12-17 06:11

    The C++ std::thread class is really just a minimal interface layered on top of some more complete implementation-defined threading package. As such, it only defines a tiny amount of functionality -- creating new threads, detach, and join. That's pretty much it -- there's no standard way of managing, scheduling, stopping/starting/killing threads or doing much else.

    There is a native_handle method that returns an implementation-defined type which can probably be used to do what you want, depending on the implementation.

    0 讨论(0)
  • 2020-12-17 06:14

    There is no way to non-cooperatively stop a thread from running with standard C++. That doesn't mean it's impossible, but you may need to go back to your systems native handle.

    For a standard conforming way you can use synchronization primitives (e.g. an std::atomic<bool>) to set a kill flag from the outside and read it within the thread. But it still has to be the thread that finishes on its own.

    0 讨论(0)
  • 2020-12-17 06:25

    Maybe this thread_pool will help you:

    #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();
          }
    };
    

    Example of use: live On Coliru

    0 讨论(0)
提交回复
热议问题