微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

此线程池代码是否尝试双重执行任务?

如何解决此线程池代码是否尝试双重执行任务?

我已经从 https://pastebin.com/MM5kSvH6 复制了以下线程池实现。一切看起来都不错,但我无法理解第 32 行和第 71 行的逻辑。这两行不是都在尝试执行该函数吗?我想在线程池中,线程应该从任务队列中提取任务然后执行它?从这个意义上说,第 71 行看起来不错,但我对第 32 行感到困惑。为什么它没有将任务添加到队列中,而是尝试执行相同的任务?

#include <condition_variable>
#include <functional>
#include <iostream>
#include <future>
#include <vector>
#include <thread>
#include <queue>
 
class ThreadPool
{
public:
    using Task = std::function<void()>;
 
    explicit ThreadPool(std::size_t numThreads)
    {
        start(numThreads);
    }
 
    ~ThreadPool()
    {
        stop();
    }
 
    template<class T>
    auto enqueue(T task)->std::future<decltype(task())>
    {
        auto wrapper = std::make_shared<std::packaged_task<decltype(task()) ()>>(std::move(task));
 
        {
            std::unique_lock<std::mutex> lock{mEventMutex};
            mTasks.emplace([=] {
                (*wrapper)();
            });
        }
 
        mEventvar.notify_one();
        return wrapper->get_future();
    }
 
private:
    std::vector<std::thread> mThreads;
 
    std::condition_variable mEventvar;
 
    std::mutex mEventMutex;
    bool mStopping = false;
 
    std::queue<Task> mTasks;
 
    void start(std::size_t numThreads)
    {
        for (auto i = 0u; i < numThreads; ++i)
        {
            mThreads.emplace_back([=] {
                while (true)
                {
                    Task task;
 
                    {
                        std::unique_lock<std::mutex> lock{mEventMutex};
 
                        mEventvar.wait(lock,[=] { return mStopping || !mTasks.empty(); });
 
                        if (mStopping && mTasks.empty())
                            break;
 
                        task = std::move(mTasks.front());
                        mTasks.pop();
                    }
 
                    task();
                }
            });
        }
    }
 
    void stop() noexcept
    {
        {
            std::unique_lock<std::mutex> lock{mEventMutex};
            mStopping = true;
        }
 
        mEventvar.notify_all();
 
        for (auto &thread : mThreads)
            thread.join();
    }
};
 
int main()
{
    {
        ThreadPool pool{36};
 
        for (auto i = 0; i < 36; ++i)
        {
            pool.enqueue([] {
                auto f = 1000000000;
                while (f > 1)
                    f /= 1.00000001;
            });
        }
    }
 
    return 0;
}

解决方法

第 32 行添加了一个 lambda,它在调用时执行任务,而第 71 行执行 lambda。一个简单地委托给另一个。 明确地说,第 32 行只是 lambda 的一部分,它通过第 72 行的调用执行。我们没有双重执行。相反,第 72 行是执行第 32 行所属代码的那一行。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。