C++实现的简单线程池

 最近学习了一些线程池方面的内容,根据学习的内容,使用C++,基于pthread线程库实现了一个简单线程池,水平有限,可能存在很多不足,代码如下

threadpool.cpp

#include "threadpool.h"
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

CThreadPool::CThreadPool(const std::string &name) 
    : m_Name(name), m_Threads(NULL), m_ThreadNum(0), m_QueueSize(0), m_Running(false)
{
    
}

CThreadPool::~CThreadPool()
{
    if (m_Running)
    {
        Stop();
    }
}

int CThreadPool::Init(int thread_num, int queue_num)
{
    if (thread_num <= 0 || queue_num <= 0)
        return -1;

    m_QueueSize = queue_num;

    if (pthread_mutex_init(&m_Mutex, NULL) != 0)
    {
        printf("pthread_mutex_init fail\n");
        return -1;
    }

    if (pthread_cond_init(&m_QueueNotFull, NULL) != 0)
    {
        printf("pthread_cond_init fail\n");
        goto err1;
    }

    if (pthread_cond_init(&m_QueueNotEmpty, NULL) != 0)
    {
        printf("pthread_cond_init fail\n");
        goto err2;
    }
    m_ThreadNum = thread_num;
    m_Threads = (pthread_t *)calloc(thread_num, sizeof(pthread_t));
    if (m_Threads == NULL)
    {
        printf("malloc fail\n");
        goto err3;
    }
    
    m_Running = true;

    for (int i = 0; i < thread_num; i++)
    {
        if (pthread_create(&m_Threads[i], NULL, thread_task, this) != 0)
        {
            printf("pthread_create fail\n");
            goto err4;
        }
    }

    return 1;

err4:
    free(m_Threads);
err3:
    pthread_cond_destroy(&m_QueueNotEmpty);
err2:
    pthread_cond_destroy(&m_QueueNotFull);
err1:
    pthread_mutex_destroy(&m_Mutex);

    return -1;
}

void CThreadPool::Stop()
{
    if (!m_Running)
        return;

    m_Running = false;
    
    pthread_cond_broadcast(&m_QueueNotEmpty);
    pthread_cond_broadcast(&m_QueueNotFull);
    for (size_t i = 0; i < m_ThreadNum; i++)
    {
        pthread_join(m_Threads[i], NULL);
    }
    free(m_Threads);
    m_Threads = NULL;
    
    pthread_mutex_lock(&m_Mutex);
    pthread_mutex_destroy(&m_Mutex);
    pthread_cond_destroy(&m_QueueNotEmpty);
    pthread_cond_destroy(&m_QueueNotFull);
}

int CThreadPool::AddTask(func_type func, void *arg)
{
    pthread_mutex_lock(&m_Mutex);
    while (m_Tasks.size() == m_QueueSize && m_Running)
    {
        pthread_cond_wait(&m_QueueNotFull, &m_Mutex);
    }
    if (!m_Running)
    {
        pthread_mutex_unlock(&m_Mutex);
        printf("线程池已经停止工作了。。。\n");
        return -1;
    }

    TaskInfo task;
    task.func = func;
    task.arg = arg;

    m_Tasks.push(task);
    pthread_mutex_unlock(&m_Mutex);
    pthread_cond_signal(&m_QueueNotEmpty);

    return 1;
}

int CThreadPool::GetTaskNum()
{
    pthread_mutex_lock(&m_Mutex);
    int ret = m_Tasks.size();
    pthread_mutex_unlock(&m_Mutex);

    return ret;
}

void *CThreadPool::thread_task(void *arg)
{
    printf("thread_task thread id = %lu\n", pthread_self());

    CThreadPool *thread_pool = (CThreadPool *)arg;

    while (thread_pool->m_Running)
    {
        pthread_mutex_lock(&thread_pool->m_Mutex);
        while (thread_pool->m_Tasks.empty() && thread_pool->m_Running)
        {
            pthread_cond_wait(&thread_pool->m_QueueNotEmpty, &thread_pool->m_Mutex);
        }
        if (!thread_pool->m_Running)
        {
            pthread_mutex_unlock(&thread_pool->m_Mutex);
            break;
        }

        TaskInfo task = thread_pool->m_Tasks.front();
        thread_pool->m_Tasks.pop();
        pthread_mutex_unlock(&thread_pool->m_Mutex);
        pthread_cond_signal(&thread_pool->m_QueueNotFull);

        task.func(task.arg);
    }

    pthread_exit(NULL);
}

threadpool.h

#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__
#include <pthread.h>
#include <queue>
#include <string>

typedef void *(*func_type) (void *);

struct TaskInfo
{
    func_type func;
    void *arg;
};

class CThreadPool
{
public:
    explicit CThreadPool(const std::string &name = "CThreadPool");
    ~CThreadPool();
    
    int Init(int thread_num = 10, int queue_num = 64);
    
    void Stop();
    
    int AddTask(func_type func, void *arg);

    int GetTaskNum();

    const std::string &GetPoolName() const 
    { return m_Name; }

private:
    CThreadPool& operator=(const CThreadPool&);
    CThreadPool(const CThreadPool&);

private:
    static void *thread_task(void *arg);

private:
    std::string m_Name;
    pthread_mutex_t m_Mutex;
    pthread_cond_t m_QueueNotFull;
    pthread_cond_t m_QueueNotEmpty;
    pthread_t *m_Threads;
    size_t m_ThreadNum;
    std::queue<TaskInfo> m_Tasks;
    size_t m_QueueSize;
    bool m_Running;
};

#endif

test.cpp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include "threadpool.h"
#include <unistd.h>
#include <stdlib.h>

void *func(void *arg)
{
    printf("[%lu]  print:%s\n", pthread_self(), (char *)arg);
    usleep(100);
    return NULL;
}

//g++ threadpool.cpp test.cpp -o test -pthread -g -Wall
int main(int argc, char *argv[])
{
    CThreadPool ctp;
    int ret = ctp.Init(24, 128);
    if (ret < 0)
    {
        printf("Init fail\n");
        exit(EXIT_FAILURE);
    }
    printf("main thread id = [%lu]\n", pthread_self());
    for (int i = 0; i < 10000; i++)
    {
        ctp.AddTask(func, (void *)"helloworld");
    }
    
    while (1)
    {
        printf("task num = %d\n", ctp.GetTaskNum());
        if (ctp.GetTaskNum() == 0)
        {
            ctp.Stop();
            break;
        }
        else
        {
            usleep(100);
        }
    }

    return 0;
}

编译命令:

g++ threadpool.cpp test.cpp -o test -pthread -g -Wall

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值