相互依赖任务的线程池

时间:2013-10-16 16:07:58

标签: c++ multithreading threadpool

我遇到的问题是非递归情况下的线程池,并且它可以从任务(给予池的工作/功能)中获益,从而能够向池中添加更多任务。我的线程池实现的问题是第一级任务填充所有工作线程,创建第二级任务,然后在等待第二级任务完成时阻塞。由于所有工作线程都被阻塞等待第二级完成,因此第二级任务永远不会被执行,因此整个程序都会死锁。

对此有什么一般解决方案吗?可能是抢占式线程池(如果可能的话)。我确实认为任务是明确的优先级,但问题是它不会自动处理依赖关系;它需要API用户的更多工作。

提前感谢任何见解或建议。

编辑:线程池类def

class{
public:
    thread_pool() = delete;
    thread_pool(const thread_pool&) = delete;
    thread_pool(unsigned int threads);
    ~thread_pool();

    template<class T, class... Args>
    std::future<T>
    async(std::function<T(Args...)>&& f, Args&&... args);

    template<class... Args>
    std::future<void>
    async(std::function<void(Args...)>&& f, Args&&... args);

    template<class T>
    std::future<T>
    async(std::function<T()>&& f);

    std::future<void>
    async(std::function<void()>&& f);

protected:
    void init_threads();
    void join_threads();
};

1 个答案:

答案 0 :(得分:1)

您使用固定数量的线程来防止同时出现太多活动任务的情况,但是当第一级任务等待第二级任务时,该线程是不再活动,因此它不应再计入固定数量的正在运行的线程。

我认为你有两种解决方法:

  1. 在等待另一个任务时将该线程标记为 busy 并告诉线程池它可以临时创建一个新线程来替换它。 (这类似于Windows线程池CallbackMayRunLong功能)。

  2. 使用任务完成回调在第二级任务完成后恢复第一级任务,而不是等待它们。 (类似于在javascript中使用任务的方式)。

  3. 虽然更复杂,但第二个选项更灵活,std :: bind为您提供了一些保留这些回调之间状态的选项