Linux C++多线程编程的线程池设计思路

发布时间:2024-11-15 17:46:28 作者:小樊
来源:亿速云 阅读:90

设计一个线程池在Linux环境下使用C++进行多线程编程是一个常见的任务。线程池可以帮助你有效地管理线程,避免频繁地创建和销毁线程带来的开销,同时提高系统的响应性和资源利用率。以下是一个基本的线程池设计思路:

1. 定义线程池类

首先,定义一个线程池类,包含以下主要成员变量:

#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <future>

class ThreadPool {
public:
    ThreadPool(size_t min_threads, size_t max_threads);
    ~ThreadPool();

    template<typename F, typename... Args>
    std::future<typename std::result_of<F(Args...)>::type> enqueue(F&& f, Args&&... args);

private:
    void worker_thread();
    void wait_for_available_threads();
    void adjust_thread_count();

    size_t max_threads_;
    size_t min_threads_;
    size_t current_threads_;
    std::queue<std::packaged_task<void()>> work_queue_;
    std::vector<std::thread> threads_;
    std::mutex mutex_;
    std::condition_variable condition_var_;
};

2. 构造函数和析构函数

构造函数初始化线程池,设置最小和最大线程数。析构函数确保所有线程在对象销毁时正确退出。

ThreadPool::ThreadPool(size_t min_threads, size_t max_threads)
    : max_threads_(max_threads), min_threads_(min_threads), current_threads_(0) {
    for (size_t i = 0; i < min_threads; ++i) {
        worker_thread();
    }
}

ThreadPool::~ThreadPool() {
    {
        std::unique_lock<std::mutex> lock(mutex_);
        stop_ = true;
    }
    condition_var_.notify_all();
    for (auto& thread : threads_) {
        if (thread.joinable()) {
            thread.join();
        }
    }
}

3. 工作线程函数

每个工作线程运行worker_thread函数,从任务队列中取出任务并执行。

void ThreadPool::worker_thread() {
    while (true) {
        std::packaged_task<void()> task;
        {
            std::unique_lock<std::mutex> lock(mutex_);
            condition_var_.wait(lock, [this] { return stop_ || !work_queue_.empty(); });
            if (stop_ && work_queue_.empty()) {
                break;
            }
            task = std::move(work_queue_.front());
            work_queue_.pop();
        }
        task();
        adjust_thread_count();
    }
}

4. 调整线程数

adjust_thread_count函数根据当前活跃线程数和任务队列的状态调整线程数。

void ThreadPool::adjust_thread_count() {
    size_t available_threads = max_threads_ - current_threads_;
    while (available_threads > 0 && !work_queue_.empty()) {
        worker_thread();
        --available_threads;
    }
    while (current_threads_ < min_threads_ && !work_queue_.empty()) {
        worker_thread();
        ++current_threads_;
    }
}

5. 入队任务

enqueue函数将任务添加到任务队列中,并通知一个等待的线程来执行该任务。

template<typename F, typename... Args>
std::future<typename std::result_of<F(Args...)>::type> ThreadPool::enqueue(F&& f, Args&&... args) {
    using return_type = typename std::result_of<F(Args...)>::type;
    auto task = std::make_shared<std::packaged_task<return_type()>>(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
    std::future<return_type> result = task->get_future();
    {
        std::unique_lock<std::mutex> lock(mutex_);
        if (stop_) {
            throw std::runtime_error("enqueue on stopped ThreadPool");
        }
        work_queue_.push(*task);
    }
    condition_var_.notify_one();
    return result;
}

6. 使用示例

以下是一个简单的使用示例,展示了如何创建一个线程池并提交任务。

#include <iostream>
#include <future>

void task(int id) {
    std::cout << "Task " << id << " started" << std::endl;
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Task " << id << " finished" << std::endl;
}

int main() {
    ThreadPool pool(2, 5);

    std::vector<std::future<void>> results;
    for (int i = 0; i < 10; ++i) {
        results.push_back(pool.enqueue(task, i));
    }

    for (auto& result : results) {
        result.wait();
    }

    return 0;
}

这个示例创建了一个包含2个最小线程和5个最大线程的线程池,并提交了10个任务。线程池会自动管理线程的创建和销毁,确保任务能够高效地执行。

推荐阅读:
  1. Linux 多线程编程
  2. linux c++ 服务器端开发面试必看书籍整理

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:C++多线程在Linux服务器开发中的应用

下一篇:如何在Linux C++中实现线程安全的队列

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》