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

1 回答 1

1

您正在使用固定数量的线程来防止同时存在过多活动任务的情况,但是当一级任务等待二级任务时,该线程不再处于活动状态,因此不应再计入朝着固定数量的运行线程。

在我看来,您有两种解决方法:

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

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

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

于 2013-10-17T10:14:26.933 回答