文档章节

一个简单的线程池模型实现

西昆仑
 西昆仑
发布于 2012/06/13 21:47
字数 763
阅读 846
收藏 7

1. 简介

在EPoll通信模型中,我们常常使用如下的处理方法:

就是将触发的事件交给线程去做而EPoll只管接收产生的事件,为了提高效率,我们会使用多线程(因为当事件产生的速度很快,在排队时,我们用多线程去处理,可以加快事件的处理速度),而线程池可以避免程序在响应用户的过程中频繁产生线程创建和销毁,提高程序效率。

2. 基本结构

 

处理流程:
当任务队列中有线程时,各线程中队列中取任务并执行任务
若任务队列中没有任务,各线程阻塞
若有新任务达到,唤醒一个线程,去处理新到达的任务

3. 相关元素

线程类:Thread 基于-lpthread封装了自己的线程类
(在之前的博文中有提过:http://my.oschina.net/myspaceNUAA/blog/61975)
互斥量:基于pthread_mutex_t的封装,Mutex类,用于对资源的互斥访问
信号量:基于pthread_cond_t的封装,Condition类,用于线程的等待和苏醒(没有资源陷入等待状态, 若有资源到达,要唤醒阻塞线程起来开工)
线程池:就是线程容器,任务队列的存放容器,同时将任务队列中的任务派发给线程去执行

 

4. 核心代码
4.1. 线程池启动,就要将指定数量的线程创建好

void start()
{
	for (int i = 0; i < m_nPoolSize; i++)
	{		
	    boost::function<void()>  f;
	    f = boost::bind(&ThreadPool::runInThread, this);
     	    Thread* pTd = new Thread(f,szId);
	    m_pThreads.push_back(pTd);
	    pTd->start();
	}
}

 


4.2 将任务交付给线程池:

/*********************************************************
函数名:run
功能:	向线程池中注入任务,插入到任务队列中
参数:	task 运行任务
**********************************************************/
void run(ThreadPool::Task &task)
{
	MutexLock mutexLock(m_mutex);
	m_tasks.push_back(task);
	m_cond.notify(); //有新资源,要唤醒一个线程去处理任务
}

 

 

 

4.3 如何将Task派发给各线程去执行

 

在线程池创建线程时,每个线程的运行函数都是:ThreadPool::runInThread,也就是说,每个线程通过这个函数从任务队列中取任务并执行,新任务到了后在任务队列中排队,那个线程有空,自然会被唤醒去取任务并执行。

 

void runInThread()
{
   while(m_bRunning)
   {
	if (!m_tasks.empty())
	{
	   ThreadPool::Task task = takeTask();
           if (task)
               task();
        }
   }
}

 

 

 

 5. 测试程序以及测试结果:

#include <iostream>
#include "ThreadPool.h"
using namespace std;

void function(int a, int b)
{
    int sum = a + b;
    cout<<"function: sum is "<<sum<<endl;
}

int main()
{
    ThreadPool threadPool(10, "ThreadPool Of Scott");
    threadPool.start();

    boost::function<void()> f;
    for (int i = 0; i < 20; i++)
    {
	f = boost::bind(function, i, i+1);
	threadPool.run(f); //依次把任务交给线程池
    }

    sleep(1000*60);
    return 0;
}

 

运行结果:

function: sum is 1
function: sum is 3
function: sum is 5
function: sum is 7
function: sum is 9
function: sum is 11
function: sum is 13
function: sum is 15
function: sum is 17
function: sum is 19
function: sum is 21
function: sum is 23
function: sum is 25
function: sum is 27
function: sum is 29
function: sum is 31
function: sum is 33
function: sum is 35
function: sum is 37
function: sum is 39

 

注:模型参考自陈硕MUDUO网络通信库

 

© 著作权归作者所有

共有 人打赏支持
西昆仑

西昆仑

粉丝 136
博文 141
码字总数 102735
作品 0
南京
高级程序员
私信 提问
加载中

评论(3)

西昆仑
西昆仑

引用来自“WILLBeSoSo”的评论

这个是muduo库下的线程池模型吧。。很不错的
是的。。。。
WILLBeSoSo
WILLBeSoSo
这个是muduo库下的线程池模型吧。。很不错的
双子座
双子座
其实这个事情我们一直在做。。。
SOCKET各种模型下并发数量

1、普通的阻塞和非阻塞编程。 利用线程池技术和内存池,SOCKET池技术,基本可以处理一千五百个左右的SOCKET连接,但我们一般使用的机器大约有两M内存,而在不改变线程堆栈的大小情况下,我们...

小报童
2013/03/02
0
0
基于事件的 NIO 多线程服务器

JDK1.4 的 NIO 有效解决了原有流式 IO 存在的线程开销的问题,在 NIO 中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个 CPU 的处理能...

恶魔在江湖
2014/03/05
0
0
模仿Tomcat的BIO,NIO线程模型

模仿Tomcat的BIO模型,来一个消息,分配一个线程处理. 则主线程池代码如下 package com.guanjian; import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorS......

算法之名
07/10
0
0
源码|从串行线程封闭到对象池、线程池

今天讲一个牛逼而实用的概念,。是串行线程封闭的典型应用场景;糅合了对象池技术,但核心实现不依赖于对象池,很容易产生误会。本文从串行线程封闭和对象池入手,最后通过源码分析线程池的核...

猴子007
2017/11/14
0
0
第十五章:选择正确的线程模型

本章介绍 线程模型(thread-model) 事件循环(EventLoop) 并发(Concurrency) 任务执行(task execution) 任务调度(task scheduling) 线程模型定义了应用程序或框架如何执行你的代码,选择应用程...

李矮矮
2016/09/27
15
0

没有更多内容

加载失败,请刷新页面

加载更多

Sping之项目中pofile的应用

工程中,我们必须要面对的一件事就是, 开发环境中使用的数据库连接地址等与生产上的不同, 如果上线, 那么我们是否还要手动修改这些地址么, 这样做有很多弊端, 不方便, 这时我们就可以使用spr...

克虏伯
5分钟前
0
0
Linux中安装MySQL

Linux中安装MySQL 一、准备工作 此处准备的操作系统位CentOS 7。 MySQL安装包: MySQL-server-5.6.29-1.linux_glibc2.5.x86_64.rpm MySQL-client-5.6.29-1.linux_glibc2.5.x86_64.rpm 将准备......

星汉
10分钟前
0
0
深入理解Hadoop之HDFS架构

Hadoop分布式文件系统(HDFS)是一种分布式文件系统。它与现有的分布式文件系统有许多相似之处。但是,与其他分布式文件系统的差异是值得我们注意的: HDFS具有高度容错能力,旨在部署在低成...

架构师springboot
14分钟前
0
0
MaxCompute表设计最佳实践

MaxCompute表设计最佳实践 产生大量小文件的操作 MaxCompute表的小文件会影响存储和计算性能,因此我们先介绍下什么样的操作会产生大量小文件,从 而在做表设计的时候考虑避开此类操作。 使用...

阿里云官方博客
15分钟前
0
0
云上领跑,快人一步:华为云抢先发布Redis5.0

12月17日,华为云在DCS2.0的基础上,快人一步,抢先推出了新的Redis 5.0产品,这是一个崭新的突破。目前国内在缓存领域的发展普遍停留在Redis4.0阶段,华为云率先发布了Redis5.0,全面展现了...

中间件小哥
15分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部