c语言编程笔录

首页 >   > 笔记大全

笔记大全

怎么使用C++单例模式实现线程池

更新时间:2023-10-26

什么是单例模式?

单例模式是设计模式中的一种,用于控制一个类只能被实例化一次,保证全局只有一个实例可以被访问。在多线程环境下,需要考虑线程安全的实现方式。接下来将使用C++代码来实现一个线程池,并结合单例模式来确保全局只有一个线程池实例。

线程池的实现

线程池是一种管理和复用线程的机制,可以在需要的时候执行任务,并将执行结果返回。下面是一个简单的线程池类Threadpool的实现:

class Threadpool {
private:
    std::vector workers;  // 存储线程的容器
    std::queue> tasks;  // 存储任务的队列
    std::mutex queueMutex;  // 保护任务队列的互斥量
    std::condition_variable condition;  // 用于线程间条件变量的同步

public:
    Threadpool(size_t numThreads) {
        for (size_t i = 0; i < numThreads; ++i) {
            workers.emplace_back([this]() {
                while (true) {
                    std::function task;
                    {
                        std::unique_lock lock(queueMutex);
                        condition.wait(lock, [this]() {
                            return !tasks.empty();
                        });
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    // 向线程池中添加任务
    template
    void addTask(F&& task) {
        {
            std::lock_guard lock(queueMutex);
            tasks.push(std::forward(task));
        }
        condition.notify_one();
    }

    // 等待所有任务完成并清空线程池
    void join() {
        for (auto& worker : workers) {
            worker.join();
        }
    }
};

单例模式的实现

为了确保全局只有一个线程池实例,可以使用单例模式来实现。下面是一个简单的单例模式的实现:

class Singleton {
private:
    static std::shared_ptr instance;  // 单例实例指针

public:
    static std::shared_ptr getInstance() {
        static std::mutex mutex;
        if (!instance) {
            std::lock_guard lock(mutex);
            if (!instance) {
                instance = std::make_shared(numThreads);  // 创建线程池实例
            }
        }
        return instance;
    }
};

std::shared_ptr Singleton::instance = nullptr;

在多线程环境下,通过使用std::mutex来保护instance的访问,确保线程安全。getInstance函数中使用双重检查锁定模式,避免创建多个实例。

总结

通过将线程池类与单例模式相结合,确保全局只有一个线程池实例可以被访问,在多线程环境下保证线程安全。单例模式的实现可以通过使用互斥量来保护实例访问,并使用双重检查锁定模式来避免创建多个实例。