2021-01-13

#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

class CThread
{
public:
    typedef void(*threadFun_t)(void* arg);
    void EXIT_ERROR(const char* msg);
    CThread(const threadFun_t& threadRoutine, void* arg);
    void start();
    void join();
    ~CThread();
    static void* threadGuide(void* arg);
    pthread_t getThreadId(void);
private:
    bool m_isRunning;                           //该线程是否运行
    pthread_t m_threadId;                       //线程ID
    threadFun_t m_threadRoutine;                //线程入口函数
    void* m_threadArg;                          //线程入口函数参数
};

#include "CPthread.h"
#include <iostream>

using namespace std;

void CThread::EXIT_ERROR(const char* msg)
{
    perror(msg);
    exit(-1);
}

CThread::CThread(const threadFun_t& threadRoutine, void* arg)
{
    m_isRunning = false;
    m_threadId = 0;
    m_threadRoutine = threadRoutine;
    m_threadArg = arg;
}

void CThread::start()
{
    pthread_attr_t attr;
    if (!pthread_attr_init(&attr)) {
        //设置线程的继承:新的线程继承策略和参数来自于schedpolicy和schedparam属性中显式设置的调度信息!
        if ((!pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED))) {
            //设置线程的调度策略:其他调度策略(轮转法,先进先出)
            if (!pthread_attr_setschedpolicy(&attr, SCHED_OTHER)) {
                //设置线程的作用域:系统级调用(进程内竞争调用)
                if (!pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) {}
                else {
                    EXIT_ERROR("set thread scope failed");
                }
            }
            else {
                EXIT_ERROR("set thread policy failed");
            }
        }
        else {
            EXIT_ERROR("set thread herit failed");
        }
    }
    else {
        EXIT_ERROR("attr init failed");
    }

    if ((!pthread_create(&m_threadId, &attr, threadGuide, this))) {}
    else {
        EXIT_ERROR("thread create failed");
    }
    m_isRunning = true;
}

void CThread::join()
{
    if (m_isRunning) {
        if (!pthread_join(m_threadId, NULL)) {}
        else {
            perror("pthread join failed");
        }
    }
    m_isRunning = false;
}

CThread::~CThread()
{
    //如果线程正在执行,则分离此线程.为回收资源
    if (m_isRunning) {
        if (!pthread_detach(m_threadId)) {}
        else {
            EXIT_ERROR("thread detach failed");
        }
    }
}

void* CThread::threadGuide(void* arg)
{
    CThread* p = static_cast<CThread*>(arg);
    p->m_threadRoutine(p->m_threadArg);
    return NULL;
}

pthread_t CThread::getThreadId(void)
{
    return m_threadId;
}

 

#include "CThreadPool.h"
#include <sys/types.h>
#include <signal.h>

CThraedPool::CThraedPool(size_t tasksSize, size_t threadsSize)
{
    m_tasksSize = tasksSize;
    m_threadsSize = threadsSize;
    m_waitCount = threadsSize;
    m_threadsMax = MAX_THREADNUM;
    m_isQuit = false;
    pthread_mutex_init(&m_mutex, NULL);
    pthread_cond_init(&m_cond, NULL);
    //signal(SIGINT, CThraedPool::pthreadfun);
}

void CThraedPool::start()
{
    m_isQuit = false;
    m_threads.reserve(m_threadsSize);
    for (size_t i = 0; i < m_threadsSize; i++)
    {
        m_threads.push_back(new CThread(threadRoutine, (void*)this));
        m_threads[i]->start();                         //开始创建线程
    }
}

void CThraedPool::stop()
{
    pthread_mutex_lock(&m_mutex);
    m_isQuit = true;
    pthread_cond_broadcast(&m_cond);//子线程有可能在忙,有可能在等

    for (int i = m_threadsSize - 1; i >= 0; i--)
    {
        m_threads[i]->join();
        delete(m_threads[i]);
        m_threads.pop_back();
    }
    pthread_mutex_destroy(&m_mutex);
    pthread_cond_destroy(&m_cond);
    pthread_mutex_lock(&m_mutex);
    printf("threadpool quiting...\n");
}

void CThraedPool::addTask(Task task)
{
    //一请求一线程
    cout << "add a task......" << endl;
    if (m_threadsSize < m_threadsMax && m_waitCount == 0)
    {
        pthread_mutex_lock(&m_mutex);
        m_threads.push_back(new CThread(threadRoutine, (void*)this));
        m_tasksqueue.push(task);
        pthread_mutex_unlock(&m_mutex);
        m_threads[m_threads.size() - 1]->start();
        m_threadsSize++;
    }
    else
    {
        pthread_mutex_lock(&m_mutex);
        m_tasksqueue.push(task);
        pthread_mutex_unlock(&m_mutex);
    }

    m_tasksSize++;
    pthread_cond_signal(&m_cond);
}

int CThraedPool::getTaskCount()
{
    return this->m_workqueue.size();
}

void CThraedPool::pthreadfun(int no)
{
    cout << "%%%%%%%%%" << no << endl;
}

CThraedPool::~CThraedPool()
{
    if (!m_isQuit)
    {
        stop();
    }
}

void  CThraedPool::threadRoutine(void* arg)
{
    CThraedPool* p = static_cast<CThraedPool*>(arg);
    while (!(p->m_isQuit))
    {
        Task task = p->take();
        if (task)
        {
            task();
            pthread_mutex_lock(&(p->m_mutex));
            p->m_workqueue.erase(pthread_self());         //从工作队列中删除
            p->m_tasksSize--;
            pthread_mutex_unlock(&(p->m_mutex));
        }
    }
    pthread_mutex_lock(&(p->m_mutex));
    p->m_threadsSize--;
    pthread_mutex_unlock(&(p->m_mutex));
    if (p->m_threadsSize == 0)
    {
        pthread_cond_signal(&p->m_cond);
    }
    printf("a thread quiting...\n");
    return;
}

Task CThraedPool::take()
{
    if (m_tasksqueue.empty() && !m_isQuit)                                   //任务队列为空,一直睡眠
    {
        pthread_mutex_lock(&m_mutex);
        m_waitCount++;
        //cout << "waiting......" << endl;
        pthread_cond_wait(&m_cond, &m_mutex);
        m_waitCount--;
        //cout << "wakeup......" << endl;
        pthread_mutex_unlock(&m_mutex);
    }
    else if (!m_tasksqueue.empty() && !m_isQuit)
    {
        Task task = m_tasksqueue.front();
        pthread_mutex_lock(&(m_mutex));
        m_tasksqueue.pop();
        m_workqueue.insert(pair<pthread_t, Task>(pthread_self(), task));   //移入工作队列
        pthread_mutex_unlock(&m_mutex);
        return task;
    }
    return NULL;
}


 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值