c++线程池

1.线程池用来干嘛

在这里插入图片描述
用户有任务需要执行,向任务队列中加入任务,线程池不断尝试从任务队列取出任务,执行任务。

2.代码

#ifndef PTHREAD_POOL_H
#define PTHREAD_POOL_H

#include <queue>
#include <pthread.h>
//线程池类
class pthreadPool
{
private:
	//任务
    struct user_data
    {
        void *(*func)(void *);
        void *arg;
    };
    //每个线程有一个work
    struct  work
    {
        pthread_t pthread_id;
        bool is_working;
        user_data *user;
        pthreadPool *pool;
    };
public:
    //仅向用户提供的方法
    pthreadPool(int max_pthread, int max_work);
    ~pthreadPool();
    bool add_work(void *(*func)(void *), void *arg, int len);
private:
    bool m_add_work(user_data *user);
    //线程运行函数不能有隐含this指针参数
    static void *m_run(void *arg);
    void pthread_loop(work *my_work);
private:
    int m_max_thread;
    int m_free_thread;
    int m_max_work;
    work *m_works;
    pthread_cond_t m_cond;
    pthread_mutex_t m_lock;
    //任务队列
    std::queue<user_data *> m_queue;
    bool m_stop;
};

#endif
#include <iostream>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include "pthreadPool.h"

using namespace std;
//线程创建、分离属性、初始化成员变量
pthreadPool::pthreadPool(int max_pthread, int max_work): m_max_thread(max_pthread), m_max_work(max_work), m_free_thread(max_pthread)
{
    if( max_pthread <= 0 || max_work <= 0 )
    {
        return;
    }
    //初始化锁、条件变量、成员变量
    if(pthread_mutex_init(&m_lock, NULL))
    {
        perror("mutex_init");
    }
    if(pthread_cond_init(&m_cond, 0))
    {
        perror("cond_init");
    }
    m_stop = false;
    //创建工作队列
    m_works = new(std::nothrow) work[m_max_work];
    if(m_works == NULL)
    {
        perror("new work");
        return;
    }
    //创建线程、分离属性
    for(int i = 0; i < m_max_thread; i++)
    {
        if(pthread_create(&m_works[i].pthread_id, NULL, m_run, (void *)&m_works[i]))
        {
            perror("pthread_create");
        }
        m_works[i].pool = this;
        m_works[i].is_working = false;
        pthread_detach(m_works[i].pthread_id);
        
    }
}
//设置停止线程参数,唤醒线程,释放空间
pthreadPool::~pthreadPool()
{
    m_stop = true;
    //TODO:线程强制退出?
    pthread_cond_broadcast(&m_cond);

    delete[]m_works;
}
//创建user_data,调用内部add,len要非0
bool pthreadPool::add_work(void *(*func)(void *), void *arg, int len)
{
    user_data *my_user_data = new(std::nothrow) user_data;
    if(my_user_data == NULL)
    {
        return false;
    }
    my_user_data->func = func;
    my_user_data->arg = malloc(len);
    if(my_user_data == NULL)
    {
        delete my_user_data;
        return false;
    }
    memcpy(my_user_data->arg, arg, len); 
    if(!m_add_work(my_user_data))
    {
        free(my_user_data->arg);
        delete my_user_data;
        return false;
    }
    return true;
}
bool pthreadPool::m_add_work(user_data *user)
{
    if(m_queue.size() >= m_max_work)
    {
        return false;
    }
    m_queue.push(user);
    return true;
}
//静态线程运行函数
void *pthreadPool::m_run(void *arg)
{
    //sleep(20);
    work *my_work = (work *)arg;
    my_work->pool->pthread_loop(my_work);
}
//循环等待任务队列,处理任务
void pthreadPool::pthread_loop(work *my_work)
{
    while(1)
    {
        pthread_mutex_lock(&m_lock);
        while(m_queue.empty())
        {
            if(m_stop)
            {
                break;
            }
            pthread_cond_wait(&m_cond, &m_lock);
        }
        if(m_stop)
        {
            pthread_mutex_unlock(&m_lock);
            break;
        }
        //从任务队列取出任务,更新数据,解锁,执行
        struct user_data * my_user_data = m_queue.front();
        m_queue.pop();
        m_free_thread--;
        pthread_mutex_unlock(&m_lock);

        my_work->is_working = true;
        my_user_data->func(my_user_data->arg);
        my_work->is_working = false;

        pthread_mutex_lock(&m_lock);
        m_free_thread++;
        pthread_mutex_unlock(&m_lock);
        //任务执行完毕,释放资源
        free(my_user_data->arg);
        delete my_user_data;
    }

    //线程结束,资源在虚构中释放
}

3.测试代码

#include <iostream>
#include <unistd.h>
#include "pthreadPool.h"

using namespace std;
void* hello(void *arg)
{
    int *day = (int *)arg;
    std::cout << "today is " << *day << std::endl;
    return NULL;
}

int day = 10;
int main()
{
    pthreadPool pool(8, 20);
    for(int i = 0; i < 10; i++)
    {
        if( !pool.add_work(hello, (void *)&day, sizeof(i)) )
        {
            cout << "添加失败" << endl;
        }
    }
    sleep(10);
    // hello(&day);
    return 0;
}

4.结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值