Оболочка нити с пользовательской функцией уничтожения - PullRequest
0 голосов
/ 10 января 2020

Позвольте мне начать с короткого примера

class A
{
public:
  A() :
    thread_([this] {
      std::unique_lock<std::mutex> lk(mtx_);
      cv_.wait(lk, [this] { return quit_; });
    })
  {
    throw std::exception();
  }

  ~A()
  {
    quit_ = true;
    cv_.notify_one();
    thread_.join();
  }

private:
  bool quit_ = false;
  std::mutex mtx_;
  std::condition_variable cv_;
  std::thread thread_;
};

int main()
{
  try { A a; }
  catch (...) {}
  // Does not reach this point
}

Поскольку в конструкторе создается исключение, элементы уничтожаются в обратном порядке. член thread_ по-прежнему доступен для соединения, поэтому вызывается терминатор.

Довольно просто написать класс-оболочку потока с настраиваемым деструктором.

Например, что-то вроде этого:

class ThreadWrapper
{
public:
    ThreadWrapper(std::function<void(std::thread & t)> onDestruct, std::thread&& thread) :
        onDestruct_(onDestruct),
        thread_(std::move(thread))
    {
    }

    ~ThreadWrapper()
    {
        onDestruct_(thread_);
    }
private:
    std::function<void(std::thread & t)> onDestruct_;
    std::thread thread_;
};

class B
{
public:
    B() :
        thread_(
        [this](std::thread& t) {
            quit_ = true;
            cv_.notify_one();
            t.join();
        },
        std::thread([this] {
            std::unique_lock<std::mutex> lk(mtx_);
            cv_.wait(lk, [this] { return quit_; });
        }))
    {
        throw std::exception();
    }

private:
    bool quit_ = false;
    std::mutex mtx_;
    std::condition_variable cv_;
    ThreadWrapper thread_;
};

Однако, я был удивлен, что не нашел что-то подобное в библиотеке наддува. Самое близкое, что я нашел, это scoped_thread, который позволяет вам передавать указанное c действие в качестве параметра шаблона.

Я что-то упустил?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...