引言
在Linux下,线程池是一种常见的并发编程模型,它能够有效地管理多个线程,提高系统的性能和资源利用率。通过线程池,可以实现多生产者多消费者模型,有效地处置惩罚并发任务,提升系统的响应速度和吞吐量。在本文中,我们将深入探讨怎样在Linux情况下创建线程池,以及线程池的实现原理和使用本事。通过深入明白线程池的概念和应用,我们可以更好地应对复杂的并发编程场景,从而提升系统的稳固性和性能表现。让我们一起探索Linux下线程池的奥秘,为并发编程的天下增添新的色彩!
一、线程池简单介绍
线程池是一种并发编程技术,用于管理和复用多个线程,以提高系统的性能和资源利用率。在线程池中,肯定命量的线程被预先创建并保存在池中,当需要执行任务时,从线程池中选择一个空闲的线程来处置惩罚任务,任务执行完毕后,线程将返回到线程池中等待下一个任务。
通过使用线程池,可以克制频仍地创建和销毁线程,减少了线程创建和销毁的开销,同时也控制了并发线程的数量,克制系统资源被过度占用。线程池还可以根据系统负载情况动态调整线程数量,以更好地顺应不同的工作负载。
二、Linux下线程池代码
⭕Makefile文件
- thread_pool:testMain.cpp
- g++ -o $@ $^ -std=c++11 -lpthread #-DDEBUG_SHOW
- clean:
- rm -f thread_pool
复制代码 这个 Makefile 包含了两个规则:一个用于编译名为"testMain.cpp"的程序并天生名为"thread_pool"的可执行文件,另一个用于清算天生的可执行文件。你可以使用"make"命令编译程序,使用"make clean"命令清算天生的可执行文件。
⭕ . h 头文件
✅Task.hpp
- #pragma once
- #include <iostream>
- #include <string>
- #include <functional>
- // 定义函数类型 func_t,用于表示可以接受两个整型参数并返回一个整型结果的函数
- typedef std::function<int(int, int)> func_t;
- // Task 类,表示一个任务
- class Task
- {
- public:
- // 默认构造函数
- Task() {}
- // 带参数的构造函数,初始化任务的成员变量
- Task(int x, int y, func_t func) : x_(x), y_(y), func_(func)
- {}
- // 重载 () 运算符,实现任务的执行
- void operator()(const std::string &name)
- {
- // 在控制台输出任务执行的结果
- std::cout << "线程 " << name << " 处理完成, 结果是: " << x_ << "+" << y_ << "=" << func_(x_, y_) << std::endl;
- }
- public:
- int x_; // 任务的参数 x
- int y_; // 任务的参数 y
- func_t func_; // 保存任务所需执行的函数
- };
复制代码 ✅thread.hpp
- #pragma once
- #include <iostream>
- #include <string>
- #include <cstdio>
- // 定义函数指针类型 fun_t,表示可以接受一个 void* 类型参数并返回一个 void* 类型结果的函数指针
- typedef void *(*fun_t)(void *);
- // 线程数据结构,用于保存线程的参数和名称
- class ThreadData
- {
- public:
- void *args_; // 线程参数
- std::string name_; // 线程名称
- };
- // 线程类,用于创建和管理线程
- class Thread
- {
- public:
- // 构造函数,初始化线程对象
- Thread(int num, fun_t callback, void *args) : func_(callback)
- {
- // 设置线程名称为 "Thread-num"
- char nameBuffer[64];
- snprintf(nameBuffer, sizeof nameBuffer, "Thread-%d", num);
- name_ = nameBuffer;
- // 设置线程数据的参数和名称
- tdata_.args_ = args;
- tdata_.name_ = name_;
- }
- // 启动线程
- void start()
- {
- pthread_create(&tid_, nullptr, func_, (void*)&tdata_);
- }
- // 等待线程结束
- void join()
- {
- pthread_join(tid_, nullptr);
- }
- // 获取线程名称
- std::string name()
- {
- return name_;
- }
- // 析构函数
- ~Thread()
- {
- }
- private:
- std::string name_; // 线程名称
- fun_t func_; // 线程执行的函数指针
- ThreadData tdata_; // 线程数据
- pthread_t tid_; // 线程 ID
- };
复制代码 ✅threadPool.hpp
⭕ . cpp 文件
✅testMain.cpp
- #include "threadPool.hpp" // 包含线程池头文件
- #include "Task.hpp" // 包含任务类的头文件
- #include <ctime>
- #include <cstdlib>
- #include <iostream>
- #include <unistd.h>
- int main()
- {
- srand((unsigned long)time(nullptr) ^ getpid()); // 初始化随机数种子
- // 获取线程池单例并运行线程
- ThreadPool<Task>::getThreadPool()->run();
- while(true)
- {
- // 生产任务的过程,制作任务的时候,要花时间
- int x = rand() % 100 + 1; // 随机生成一个范围在1到100之间的整数x
- usleep(7721); // 模拟制作任务需要的时间
- int y = rand() % 30 + 1; // 随机生成一个范围在1到30之间的整数y
- Task t(x, y, [](int x, int y) -> int { // 创建任务对象t,执行加法操作
- return x + y;
- });
- std::cout << "制作任务完成: " << x << "+" << y << "=?" << std::endl; // 输出任务信息
- // 推送任务到线程池中
- ThreadPool<Task>::getThreadPool()->pushTask(t);
- sleep(1); // 暂停一秒钟
- }
- return 0;
- }
复制代码 这段代码主要实现了一个简单的任务生产者,不断地天生任务并将任务推送到线程池中执行。
三、线程池的优点
线程池能够有效地管理线程,提高系统的性能和响应速度,同时简化了线程管理的复杂性,是多线程编程中常用的一种技术。下面是它的优点
- 提高性能:线程池可以减少线程创建和销毁的开销,通过重用线程,克制了频仍地创建和销毁线程所带来的性能消耗。
- 控制并发度:线程池可以限定同时执行的线程数量,从而控制系统的并发度,防止由于过多线程导致系统资源被耗尽。
- 提高响应速度:由于线程池中的线程已经创建好并处于就绪状态,当任务到达时可以立即执行,从而减少了任务等待执行的时间,提高了系统的响应速度。
- 简化线程管理:线程池封装了线程的创建、销毁、调理等操作,简化了线程管理的复杂性,提高了代码的可维护性。
- 控制资源占用:线程池可以限定系统中同时存在的线程数量,从而控制系统对资源(如内存、CPU)的占用,防止资源被耗尽导致系统瓦解。
总而言之,线程池提供了一种高效、可控的线程管理机制,实用于处置惩罚大量并发任务的场景,是提高系统性能和响应速度的紧张工具之一。
温馨提示
感谢您对博主文章的关注与支持!假如您喜欢这篇文章,可以点赞、评论和分享给您的同砚,这将对我提供巨大的鼓励和支持。另外,我筹划在未来的更新中持续探讨与本文相干的内容。我会为您带来更多关于Linux以及C++编程技术问题的深入解析、应用案例和趣味玩法等。假如感兴趣的话可以关注博主的更新,不要错过任何精彩内容!
再次感谢您的支持和关注。我们期待与您创建更紧密的互动,共同探索Linux、C++、算法和编程的奥秘。祝您生存愉快,排便顺畅!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |