网络处理线程池

线程池

线程池的概念:因为创建线程池需要一定时间和分配资源。在网络I/O处理单元中,为了提高服务器响应的速度我们利用I/O多路复用(select、poll、epoll)来处理客户连接,当有一个客户连接到来时,减少客户端的等待时间,利用主线程区监听sockfd,之后将监听到的sockfd分配给子线程去处理,但是我们不可能有一个连接就创建并分配一个子线程给这个sockfd,因为这是消耗系统资源的。所以我们可以预先创建线程池。设计到线程池就要涉及到加锁、解锁、信号量(主要是用来判断有多少个空闲的线程)。

代码部分:

/*此文件是用来作为线程池使用,文件名:threadpool.h*/
#ifndef THREADPOOL_H
#define THREADPOOL_H

#include<list>
#include<cstdio>
#include<exception>
#include<pthread.h>
#include "locker.h"


template<typename T>
class threadpool
{
public:
	threadpool(int thread_number=8,int max_requests=1000);
	~threadpool();
	bool append(T* request);

private:
	/*工作线程*/
	static void* worker(void* arg);
	void run();
private:
	int m_thread_number; //线程数量
	int m_max_requests;  //最大处理数
	pthread_t* m_threads; //线程指针
	std::list<T*> m_workqueue; //请求对列
	locker m_queuelocker;   //线程锁
	sem m_queuestat;		//信号量
	bool m_stop;            //是否让线程停下来
};


template<typename T>
threadpool<T>::threadpool(int thread_number,int max_requests):
		m_thread_number(thread_number),m_max_requests(max_requests),m_stop(false),m_threads(NULL)
{
	if((thread_number<=0)||(max_requests<=0))
	{
		/*如果线程数量小于等于0或者最大请求数也小于等于0则抛出异常*/
		throw std::exception();
	}
	/*创建线程*/
    m_threads = new pthread_t[m_thread_number];
    if(!m_threads)
    {
        throw std::exception();
    }
	for(int i=0;i<thread_number;i++)
	{
		printf("create the %dth pthread\n",i);
		if(pthread_create(m_threads+i,NULL,worker,this)!=0)
		{
			/*创建失败则删除指针并抛出异常*/
			delete [] m_threads;
			throw std::exception();
		}
		/*分离线程,分离失败,删除指针和抛出异常*/
		if(pthread_detach(m_threads[i]))
		{
			delete [] m_threads;
			throw std::exception();
		}
	}
}

template<typename T>
threadpool<T>::~threadpool()
{
	delete [] m_threads;
	m_stop=true;
}

/*创建任务队列*/
template<typename T>
bool threadpool<T>::append(T* request)
{
	m_queuelocker.lock(); /*因为任务对列是所有线程共享的,所以要加锁*/
	/*任务对列的最大长度超过了要求的最大长度则表示不能再插入任务了,创建任务失败*/
	if(m_workqueue.size()>m_max_requests)
	{
		m_queuelocker.unlock();
		return false;
	}
	/*插入任务对列*/
	m_workqueue.push_back(request);
	/*解锁,信号量加1*/
	m_queuelocker.unlock();
	m_queuestat.post();
	return true;
}

template<typename T>
void* threadpool<T>::worker(void *arg)
{
	threadpool* pool = (threadpool*)arg;//强制转换类型
	pool->run();
	return pool;
}

template<typename T>
void threadpool<T>::run()
{
	while(!m_stop)
	{
		m_queuestat.wait();  //等待信号量
		m_queuelocker.lock();  //等待锁
		if(m_workqueue.empty())
		{
			/*任务对列为空*/
			m_queuelocker.unlock();
			continue;
		}
		T* request = m_workqueue.front();//取出一个任务
		m_workqueue.pop_front();
		m_queuelocker.unlock();
		if(!request)
		{
			continue;
		}
		request->process();
	}
}

#endif

1、下面创建locker.h代码:

/*此文件为locker.h*/
#ifndef LOCKER_H
#define LOCKER_H

#include <exception>
#include <pthread.h>
#include <semaphore.h>

class sem
{
public:
    sem()
    {
        if( sem_init( &m_sem, 0, 0 ) != 0 )
        {
            throw std::exception();
        }
    }
    ~sem()
    {
        sem_destroy( &m_sem );
    }
    bool wait()
    {
        return sem_wait( &m_sem ) == 0;
    }
    bool post()
    {
        return sem_post( &m_sem ) == 0;
    }

private:
    sem_t m_sem;
};

class locker
{
public:
    locker()
    {
        if( pthread_mutex_init( &m_mutex, NULL ) != 0 )
        {
            throw std::exception();
        }
    }
    ~locker()
    {
        pthread_mutex_destroy( &m_mutex );
    }
    bool lock()
    {
        return pthread_mutex_lock( &m_mutex ) == 0;
    }
    bool unlock()
    {
        return pthread_mutex_unlock( &m_mutex ) == 0;
    }

private:
    pthread_mutex_t m_mutex;
};

class cond
{
public:
    cond()
    {
        if( pthread_mutex_init( &m_mutex, NULL ) != 0 )
        {
            throw std::exception();
        }
        if ( pthread_cond_init( &m_cond, NULL ) != 0 )
        {
            pthread_mutex_destroy( &m_mutex );
            throw std::exception();
        }
    }
    ~cond()
    {
        pthread_mutex_destroy( &m_mutex );
        pthread_cond_destroy( &m_cond );
    }
    bool wait()
    {
        int ret = 0;
        pthread_mutex_lock( &m_mutex );
        ret = pthread_cond_wait( &m_cond, &m_mutex );
        pthread_mutex_unlock( &m_mutex );
        return ret == 0;
    }
    bool signal()
    {
        return pthread_cond_signal( &m_cond ) == 0;
    }

private:
    pthread_mutex_t m_mutex;
    pthread_cond_t m_cond;
};

#endif

下面是worker.h代码

#ifndef WORKER_H
#define WORKER_H

#include<stdio.h>



class Worker
{
public:
    Worker(){};
    void process()
    {
        int sum=0;
        for(int i=0;i<10;i++)
        {
            sum += i;
        }
        printf("sum=%d\n",sum);
    }
};

#endif

下面是主函数

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include "locker.h"
#include "worker.h"
#include "threadpool.h"


int main()
{
    Worker* work = new Worker[8];
    threadpool<  Worker >* pool =new threadpool<  Worker >;
    //pool = ;
    for(int i=0;i<8;i++){
        pool->append(work+i);
    }
    sleep(1000000);//给线程一定的运行时间
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚嵌入式学习同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值