局部线程池和全局线程池_进程池和线程池 - 半同步/半反应堆线程池实现

f0238f3f39288fe710b6ef78fabdfc5b.png

该线程池的通用性高的多,因为它使用一个工作队列完全解除了主线程和工作线程之间的耦合关系:

主线程网工作队列中插入任务,工作线程通过竞争来取得任务并执行它。

不过,如果要将该线程池应用到实际服务器程序中,那么我们必须保证所有客户请求都是无状态的,因为同一个连接上的不同请求可能会由不同的线程处理

示例代码如下,代码中的locker.h引自多线程编程 - 线程同步机制

#ifndef THREADPOOL_H#define THREADPOOL_H#include #include #include #include #include "locker.h"/*线程池类,将它定义为模板类是为了代码复用。模板参数T是任务类*/template class threadpool{public:    /*参数thread_number是线程池中线程的数量,    max_request是请求队列中最多允许的、等待处理的请求的数量*/    threadpool(int thread_number = 8, int max_requests= 10000);    ~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; /*描述线程池的数组,其大小为m_thread_number*/    std::list m_workqueue; /*请求队列*/    locker m_queuelocker; /*保护请求队列的互斥锁*/    sem m_queuestat; /*是否有任务需要处理*/    bool m_stop; /*是否结束线程*/};templatethreadpool::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){        throw std::exception();    }    m_threads = new pthread_t[m_thread_number];    if(!m_threads){        throw std::exception();    }    /*创建thread_numbers个个数,并将它们都设置为脱离线程*/    for(int i = 0; i < thread_number; ++i){        printf("create the %dth thread", 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();        }    }}templatethreadpool::~threadpool(){    delete [] m_threads;    m_stop = true;}templatebool threadpool::append(T* request){    /*操作工作队列时一定要加锁,因为它被所有线程共享*/    m_queuelocker.lock();    if(m_workqueue.size > m_max_requests){        m_queuelocker.unlock();        return false;    }    m_workqueue.push_back(request);    m_queuelocker.unlock();    m_queuestat.post();    return true;}templatevoid *threadpool::worker(void* arg){    threadpool * pool = (threadpool*)arg;    pool->run();    return pool;}templatevoid threadpool::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

这里需要注意的是,在C++程序中使用pthread_create函数时,该函数的第三个参数必须指向一个静态函数。而要在一个静态函数中使用类的动态成员(包括成员函数和成员变量),则只能通过如下两种方式实现:

  • 访问类的静态对象来调用。如果单例模式中。静态函数可以通过类的全局唯一实例来访问动态成员函数
  • 将类的对象作为参数参数传递给该静态函数,然后在静态函数中应用这个对象,并调用其动态代码

上述代码中,使用的是第二种方式:将线程参数设置为this指针,然后在worker函数中获取该指针并调用其动态方法run。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值