2013-10-16 60 views
0

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

这是否有任何通用的解决方案?可能是先发制人的线程池(如果甚至可能的话)。我确实认为有明确的优先任务,但问题在于它不会自动处理依赖关系;它需要更多API用户的工作。

在此先感谢您的任何见解或建议。

编辑:线程池类高清

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(); 
}; 
+0

如何阻断地图?一个一级任务是否创建一个二级任务或更多? –

+0

请澄清:您已经创建了自己的线程池,而不是使用运行时环境或开发环境提供的线程池? –

+0

@Martin:每个第n级任务可以添加任意数量的n + 1级任务。 – Tyler

回答

1

您正在使用的线程固定数量,以防止过多的活跃任务的情况下,在同一时间,但是当第一级任务等待一个二级的,那个线程不再是活动的,所以它不应该再算上固定数量的正在运行的线程。

的方式,我看到它,你必须围绕这一工作的方式有两种:

  1. 马克线程作为等待另一个任务时,告诉线程池,它可以暂时创建一个新的线程忙取代它。 (这与Windows Thread Pool CallbackMayRunLong函数类似)。

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

虽然比较复杂,第二个选项是更加灵活和std ::绑定给你的回调之间保持状态的几个选项