C++ 相互依赖任务的线程池

C++ 相互依赖任务的线程池,c++,multithreading,threadpool,C++,Multithreading,Threadpool,我有一个问题,在非递归的情况下,线程池可以很好地解决这个问题,如果任务(提供给池的工作/函数)能够向池中添加更多任务,那么它将大大受益。我的线程池实现的问题是,第一级任务填充所有工作线程,创建第二级任务,然后在等待第二级任务完成时阻塞。由于所有工作线程都在等待第二级完成时被阻塞,因此第二级任务永远不会执行,因此整个程序都会死锁 有什么通用的解决方案吗?可能是一个抢占式线程池(如果可能的话)。我确实想过让任务明确划分优先级,但问题是它不会自动处理依赖关系;它需要对API用户进行更多的工作 提前感谢

我有一个问题,在非递归的情况下,线程池可以很好地解决这个问题,如果任务(提供给池的工作/函数)能够向池中添加更多任务,那么它将大大受益。我的线程池实现的问题是,第一级任务填充所有工作线程,创建第二级任务,然后在等待第二级任务完成时阻塞。由于所有工作线程都在等待第二级完成时被阻塞,因此第二级任务永远不会执行,因此整个程序都会死锁

有什么通用的解决方案吗?可能是一个抢占式线程池(如果可能的话)。我确实想过让任务明确划分优先级,但问题是它不会自动处理依赖关系;它需要对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();
};
类{
公众:
线程池()=删除;
线程池(常量线程池&)=删除;
线程池(无符号整数线程);
~thread_pool();
模板
未来
异步(std::function&&f、Args&&Args);
模板
未来
异步(std::function&&f、Args&&Args);
模板
未来
异步(std::function&&f);
未来
异步(std::function&&f);
受保护的:
void init_threads();
void join_threads();
};

您正在使用固定数量的线程来防止同时有太多的活动任务,但当第一级任务等待第二级任务时,该线程不再处于活动状态,因此它不应再计入固定数量的运行线程

在我看来,解决这个问题有两种方法:

  • 在等待另一个任务时,将线程标记为忙碌,并告诉线程池它可以临时创建一个新线程来替换它。(这类似于Windows线程池函数)

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


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

    阻塞映射如何?一个第一级任务是否会创建一个或多个第二级任务?请澄清:您创建了自己的线程池,而不是使用运行时环境或开发环境提供的线程池?@Martin:每个第n级任务可以添加任意多个n+1级任务。@Jim:这是我的实现。它在功能上等同于std::async,但使用固定数量的线程执行。(为了防止在深度递归的情况下过度调度。)我将发布API,但代码很长,可能不必要的混乱。但是如果你想看的话,我可以贴出来。