我遇到的问题是非递归情况下的线程池,并且它可以从任务(给予池的工作/功能)中获益,从而能够向池中添加更多任务。我的线程池实现的问题是第一级任务填充所有工作线程,创建第二级任务,然后在等待第二级任务完成时阻塞。由于所有工作线程都被阻塞等待第二级完成,因此第二级任务永远不会被执行,因此整个程序都会死锁。
对此有什么一般解决方案吗?可能是抢占式线程池(如果可能的话)。我确实认为任务是明确的优先级,但问题是它不会自动处理依赖关系;它需要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();
};
答案 0 :(得分:1)
您使用固定数量的线程来防止同时出现太多活动任务的情况,但是当第一级任务等待第二级任务时,该线程是不再活动,因此它不应再计入固定数量的正在运行的线程。
我认为你有两种解决方法:
在等待另一个任务时将该线程标记为 busy 并告诉线程池它可以临时创建一个新线程来替换它。 (这类似于Windows线程池CallbackMayRunLong功能)。
使用任务完成回调在第二级任务完成后恢复第一级任务,而不是等待它们。 (类似于在javascript中使用任务的方式)。
虽然更复杂,但第二个选项更灵活,std :: bind为您提供了一些保留这些回调之间状态的选项