图.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

【线程池封装】实现简单回射服务器相关推荐

  1. LIBUV学习笔记(三)libuv中pipe/tty相关操作以及一个简单的unix域回射服务器/客户端例子...

    uv_pipe_t - Pipe handle Pipe handles provide an abstraction over local domain sockets on Unix and na ...

  2. 《UNP》随笔——“实现一个简单的回射服务器”存在的不足(信号处理)

    尽管实现了一个简单的回射服务器,但依旧存在一些不足: 服务端的子进程结束的时候,由于父进程未对子进程发送的SIGCHLD信号进行处理,会导致子进程进入僵死状态.这一点该如何解决? 客户端A向服务端B发 ...

  3. 一个简单的回射服务器

    本文编写了一个初步的简单的回射服务器例子.基本内容书上都能找到,认真看书就行了,所以尽量讲一些自己认为应该注意的地方. 功能: 客户端从标准输入读入一行文本,写给服务器:服务器读入这行文本,并回射给客 ...

  4. Linux C++ 回射服务器

    http://blog.csdn.net/qq_25425023/article/details/53914820 回射服务器就是服务端将客户端的数据发送回去. 我实现的回射服务器返回增加了时间. 服 ...

  5. Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  6. android 多线程封装,Android线程池封装库

    目录介绍 1.遇到的问题和需求 1.1 遇到的问题有哪些 1.2 遇到的需求 1.3 多线程通过实现Runnable弊端 1.4 为什么要用线程池 2.封装库具有的功能 2.1 常用的功能 3.封装库 ...

  7. linux——回射服务器

    回射服务器即客户端发送一段数据给服务器,服务器再将这段数据原封不动的发送给客户端,原理很简单,原理图如下: 以TCP协议为例,客户端.服务器代码如下: ** 服务器: ** #include < ...

  8. TCP echo_server(C++)回射服务器实现以及问题记录

    TCP echo_server(C++)回射服务器实现以及问题记录 基本运行方式: 客户端接收用户输入的字符串并发送到服务器端 服务器端将接收的字符串数据传回客户端 服务器端和客户端之间的字符串回射一 ...

  9. IOCP加Windows线程池打造高伸缩性高性能的服务器应用

    对于IOCP,搞Windows服务器编程的都不会陌生,它所表现出来的性能是其他各种WinSock模型难望其项背的.撰写本文的目的就是为让大家能够在深入理解IOCP的基础上,再来深入的挖掘Windows ...

最新文章

  1. Java-JPA:JPA
  2. 一篇文章帮你彻底搞清楚“I/O多路复用”和“异步I/O”的前世今生
  3. 关于FastStone Capture for Windows在Windows10英文系统下的中文乱码问题
  4. StackExchange.Redis 官方文档(六) PipelinesMultiplexers
  5. SpringBoot核心
  6. 一个戏精程序员的内心独白...
  7. 宏基因组 微生物组 微生态杂志简介及2019最新影响因子
  8. “数据科学”课程群与 “数据科学导论”课程建设初探
  9. 终于发现路由器里的广告秘密
  10. 使用YYLabel匹配连接
  11. ios 抓娃娃开发_可爱抓娃娃ios版_可爱抓娃娃手机版1.0.4 - 系统城
  12. 解释@Transactional注解的用法
  13. Linux在当前文件夹下打开终端
  14. 渗透测试-burp suite实战
  15. Eclipse-sdcc学习(fedoar 14)
  16. SpringBoot+mybatis+postgreSQL+thymeleaf增删改查
  17. 【电机驱动芯片(单、双极性步进电机驱动方式/四相五线和42步进电机)——ULN2003、双H桥芯片(DRV8833/DRV8825)】
  18. 移动联通基站使用介绍
  19. ChatGPT专业应用:日报速成器
  20. 【WebService】wsdl配置详解以及使用注解修改wsdl配置

热门文章

  1. Deep Network with Stochastic Depth(阅读笔记)一种随机深度的正则化方法
  2. 伦敦大学国王学院 计算机phd,重磅!伦敦国王学院全奖博士录取一枚!
  3. 男士不得不看的21种经典拍照姿势
  4. 《信息学奥赛一本通》宠物小精灵之收服
  5. bbr29_TCP BBR导致性能下降
  6. 瑞芯微PX30芯片参数和处理器介绍
  7. 通过hive sql实现报表中的MTD,YTM,YTD
  8. Spring Cloud Alibaba学习记录
  9. 超越纯CSS3,超赞阴影效果推荐-shine.js
  10. scrapy爬虫入门