【问题标题】:C++11 - Managing worker threadsC++11 - 管理工作线程
【发布时间】:2014-07-01 18:22:27
【问题描述】:

我是 C++11 中的线程新手,我想知道如何管理工作线程(使用标准库)以执行某些任务然后消失。我有一个线程池vector<thread *> thread_pool,它维护着一个活动线程列表。

假设我启动一个新线程并使用thread_pool.push_back(new thread(worker_task)) 将其添加到池中,其中worker_task 定义如下:

void worker_task()
{
    this_thread::sleep_for(chrono::milliseconds(1000));
    cout << "Hello, world!\n"
}

一旦工作线程终止,从池中可靠地移除线程的最​​佳方法是什么?主线程需要连续运行并且不能阻塞join 调用。我对代码的一般结构比对同步的复杂性更感到困惑。

编辑: 看起来我在代码中误用了池的概念。我的意思是我有一个当前正在运行的线程列表。

【问题讨论】:

  • 如果每个线程只执行一个任务,线程池的目的是什么?
  • kernel.org/pub/linux/kernel/people/paulmck/perfbook/… 在考虑构建线程池架构之前阅读此内容。
  • “池”不是这个意思……
  • @nosid 为了这个问题,我简化了情况。我正在创建的线程不会像上面显示的 worker_task 函数那么短,并且我需要能够显示所有线程在任何给定时间正在处理的内容。 thread_pool 实际上不会包含线程对象列表,但会包含与每个线程关联的元数据。

标签: multithreading c++11


【解决方案1】:

您可以使用std::thread::detach“将执行线程与线程对象分开,允许执行独立继续。一旦线程退出,所有分配的资源都将被释放。”

如果每个线程都应该使其状态可见,您可以将此功能移到线程函数中。

std::mutex mutex;
using strings = std::list<std::string>;
strings info;

strings::iterator insert(std::string value) {
    std::unique_lock<std::mutex> lock{mutex};
    return info.insert(info.end(), std::move(value));
}

auto erase(strings::iterator p) {
    std::unique_lock<std::mutex> lock{mutex};
    info.erase(p);
}

template <typename F>
void async(F f) {
    std::thread{[f] {
        auto p = insert("...");
        try {
            f();
        } catch (...) {
            erase(p);
            throw;
        }
        erase(p);
    }}.detach();
}

【讨论】:

  • 谢谢!我不知道分离功能,所以我会调查一下。但是,关于您的代码的一个问题是,擦除怎么会在捕获中?预计 f 完成后会抛出异常吗?
  • @Chirag: erase 无论函数如何终止都应该被调用。但是,我错过了成功终止的案例。改用 RAII 会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多