如何在完成后从容器中删除`std::thread`?

问题描述 投票:0回答:1

在一个类中有一个

std::list<std::thread>
,还有另一个线程可以添加一些。如何处理完成后从列表中删除线程元素的责任?

我考虑过另一个线程,它可以由完成线程通知这样做,但它对我来说似乎变得复杂,我不确定我是否遗漏了一些东西,整个事情可能只是一个坏主意。

c++ list multithreading containers responsibility
1个回答
0
投票

如果您同意使用锁,您可以跟踪队列中需要删除的任何线程,并且每次您想要创建新线程时,只需删除已完成的线程即可。

#include <thread>
#include <mutex>
#include <list>
#include <queue>

void work(auto finalizer)
{
    // do work
    finalizer();
}

struct manager
{
    void spawn()
    {
        std::lock_guard l(mut);
        // remove finished theads
        while (threads_to_destroy.size())
        {
            threads.erase(threads_to_destroy.front());
            threads_to_destroy.pop();
        }

        // create new thread at the end and get its iterator
        auto it = threads.insert(threads.end(), std::thread{});

        // start the thread with a finalizer
        auto finalizer = [this, it]() {
            std::lock_guard l(this->mut);
            this->threads_to_destroy.push(it);
        };
        *it = std::thread(finalizer);
    }
    std::list<std::thread> threads;
    std::queue<std::list<std::thread>::iterator> threads_to_destroy;
    std::mutex mut;
};

int main()
{
    manager m;
    m.spawn();
    m.spawn();
}

缺点:

  1. 异常安全性有待提高
  2. 在创建新线程之前,旧线程不会被删除
  3. 使用锁

优点:

  1. 线程安全,无竞争条件
  2. 如果队列更换为无锁队列就可以解除锁
© www.soinside.com 2019 - 2024. All rights reserved.