【线程池封装】实现简单回射服务器
图.1 线程池框架
类封装:
template<typename T>
class ThreadPool
{public:ThreadPool(int threadnum = 8, int maxreqnum = 1000);~ThreadPool(){delete [] m_Pthread;m_Stop = true;}/* 往队列添加任务 */bool Append(T *request);/* 线程函数不能执行对象成员函数,所以声明为static,此时函数不能使用对象非静态成员,故将访问的工作交给Run函数,* this 传递到args。(Work应该封装到类里面)——Singleton模式 */static void* Work(void *args);void Run(int index);private:/* 请求队列最大任务数 */int m_MaxRequestNum;/* 线程池线程数量 */int m_ThreadNum;pthread_t *m_Pthread;/* 线程是否应该结束 */bool m_Stop;/* 子线程在等待任务时,应该进入睡眠,用信号量;而资源竞争(获取队列中的一个任务)用互斥量保护 */pthread_mutex_t m_QueMutex;sem_t m_QueSem;/* 任务列表 */std::list<T *> m_WorkList;
};
创建并分离线程:
template<typename T>
ThreadPool<T>::ThreadPool(int threadnum, int maxreqnum): m_MaxRequestNum(maxreqnum), m_ThreadNum(threadnum), m_Pthread(nullptr), m_Stop(false)
{int ret;/* 信号量值小于零就block */ret = sem_init(&m_QueSem, 0, 0);if (ret == -1){printf("ThreadPool: [sem_init] failed, errno[%d]:%s\n", errno, strerror(errno));exit(-1);}m_QueMutex = PTHREAD_MUTEX_INITIALIZER;if (!m_Pthread){m_Pthread = (pthread_t *)malloc(sizeof(pthread_t) * m_ThreadNum);/* 如果分配失败,应该退出 */if (!m_Pthread){printf("ThreadPool: [malloc] failed, errno[%d]:%s\n", errno, strerror(errno));exit(-1);}}for (int i = 0; i < threadnum; ++i){/* 将this指针传递给static成员函数,实现Singleton模式 */ret = pthread_create(m_Pthread + i, nullptr, Work, this);if (ret != 0){delete [] m_Pthread;printf("ThreadPool: [pthread_create] failed, errno[%d]:%s\n", ret, strerror(ret));exit(-1);}/* 分离线程,子线程马上到执行区等待任务 */ret = pthread_detach(m_Pthread[i]);if (ret != 0){delete [] m_Pthread;printf("ThreadPool: [pthread_detach] failed, errno[%d]:%s\n", ret, strerror(ret));exit(-1); }}
}
从任务列表获取任务,互斥量用于防止多个线程共同使用一个变量,而信号量避免的由于pthread_mutex_lock带来的cpu消耗,让线程进入睡眠状态:
template<typename T>
void* ThreadPool<T>::Work(void *args)
{static int index = 0;index++;ThreadPool<T> *pthreadpool = (ThreadPool<T> *)args;pthreadpool->Run(index);return nullptr;
}template<typename T>
void ThreadPool<T>::Run(int index)
{printf("pthread:%d\n", index);while (!m_Stop){sem_wait(&m_QueSem);printf("pthread:%d\n", index);pthread_mutex_lock(&m_QueMutex);if (m_WorkList.empty()){pthread_mutex_unlock(&m_QueMutex);continue;}/* 获取一个任务 */T* request = m_WorkList.front();m_WorkList.pop_front();pthread_mutex_unlock(&m_QueMutex);if (!request){continue;}request->Process();delete request;}
}
添加任务到任务列表,并发出有新任务到来的信号:
template<typename T>
bool ThreadPool<T>::Append(T *request)
{pthread_mutex_lock(&m_QueMutex);if (m_WorkList.size() > m_MaxRequestNum){pthread_mutex_unlock(&m_QueMutex);printf("ThreadPool: [Append] failed, Client sum is over m_MaxRequestNum \n");return false;}m_WorkList.push_back(request);pthread_mutex_unlock(&m_QueMutex);sem_post(&m_QueSem);return true;
}
源码见 Github: https://github.com/jammgit/ThreadPool
【线程池封装】实现简单回射服务器相关推荐
- LIBUV学习笔记(三)libuv中pipe/tty相关操作以及一个简单的unix域回射服务器/客户端例子...
uv_pipe_t - Pipe handle Pipe handles provide an abstraction over local domain sockets on Unix and na ...
- 《UNP》随笔——“实现一个简单的回射服务器”存在的不足(信号处理)
尽管实现了一个简单的回射服务器,但依旧存在一些不足: 服务端的子进程结束的时候,由于父进程未对子进程发送的SIGCHLD信号进行处理,会导致子进程进入僵死状态.这一点该如何解决? 客户端A向服务端B发 ...
- 一个简单的回射服务器
本文编写了一个初步的简单的回射服务器例子.基本内容书上都能找到,认真看书就行了,所以尽量讲一些自己认为应该注意的地方. 功能: 客户端从标准输入读入一行文本,写给服务器:服务器读入这行文本,并回射给客 ...
- Linux C++ 回射服务器
http://blog.csdn.net/qq_25425023/article/details/53914820 回射服务器就是服务端将客户端的数据发送回去. 我实现的回射服务器返回增加了时间. 服 ...
- Android线程池封装库
目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...
- android 多线程封装,Android线程池封装库
目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...
- linux——回射服务器
回射服务器即客户端发送一段数据给服务器,服务器再将这段数据原封不动的发送给客户端,原理很简单,原理图如下: 以TCP协议为例,客户端.服务器代码如下: ** 服务器: ** #include < ...
- TCP echo_server(C++)回射服务器实现以及问题记录
TCP echo_server(C++)回射服务器实现以及问题记录 基本运行方式: 客户端接收用户输入的字符串并发送到服务器端 服务器端将接收的字符串数据传回客户端 服务器端和客户端之间的字符串回射一 ...
- IOCP加Windows线程池打造高伸缩性高性能的服务器应用
对于IOCP,搞Windows服务器编程的都不会陌生,它所表现出来的性能是其他各种WinSock模型难望其项背的.撰写本文的目的就是为让大家能够在深入理解IOCP的基础上,再来深入的挖掘Windows ...
最新文章
- Java-JPA:JPA
- 一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生
- 关于FastStone Capture for Windows在Windows10英文系统下的中文乱码问题
- StackExchange.Redis 官方文档(六) PipelinesMultiplexers
- SpringBoot核心
- 一个戏精程序员的内心独白...
- 宏基因组 微生物组 微生态杂志简介及2019最新影响因子
- “数据科学”课程群与 “数据科学导论”课程建设初探
- 终于发现路由器里的广告秘密
- 使用YYLabel匹配连接
- ios 抓娃娃开发_可爱抓娃娃ios版_可爱抓娃娃手机版1.0.4 - 系统城
- 解释@Transactional注解的用法
- Linux在当前文件夹下打开终端
- 渗透测试-burp suite实战
- Eclipse-sdcc学习(fedoar 14)
- SpringBoot+mybatis+postgreSQL+thymeleaf增删改查
- 【电机驱动芯片(单、双极性步进电机驱动方式/四相五线和42步进电机)——ULN2003、双H桥芯片(DRV8833/DRV8825)】
- 移动联通基站使用介绍
- ChatGPT专业应用:日报速成器
- 【WebService】wsdl配置详解以及使用注解修改wsdl配置