绑定cpu的线程类封装和不绑定cpu的线程类封装

绑定cpu的线程:
threadutils.h

#ifndef _THREADUTILS_H_
#define _THREADUTILS_H_

/* 使用方法
 * 创建类,继承CAbstractRunnable
 * 实现线程处理函数(可实现多个)void *run1(struct SThreadInfo* pThreadInfo);
 * 注册处理函数REGIST_RUN_FUNC(A,run1),A为类名,run1为处理函数,如下:
    class A : public CAbstractRunnable
    {
        ...
        public:
        void *run1(struct SThreadInfo *pThreadInfo);
        void *run2(struct SThreadInfo *pThreadInfo);
        REGIST_RUN_FUNC(A,run1)
        REGIST_RUN_FUNC(A,run2)
        ...
    };
    实例化类
    A a;
    启动线程
    CThreadUtils::createThreadOnCore(&a, a.GET_RUN_FUNC(run1), 0, 1);
    CThreadUtils::createThreadOnCore(&a, a.GET_RUN_FUNC(run2), 1, 1);
 */
#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#include <errno.h>
#endif

#include <string>
#include <vector>
#include <unistd.h>
#include <stdio.h>

#define THREADUTILS_PRIORITY_LOW 0
#define THREADUTILS_PRIORITY_NORMAL 1
#define THREADUTILS_PRIORITY_HIGH 2


class CAbstractRunnable;

typedef void* (*PRUNNABLE_FUNC)(void*);

//每创建一个线程都维护一个线程相关信息
struct SThreadInfo
{
#ifdef WIN32
    HANDLE hThread;
#else
    pthread_t hThread;      //线程句柄
#endif
    int bRunning;       //运行状态
    int bWatch;         //是否监护
    int coreId;         //绑定cpu
    CAbstractRunnable *pRunObj; //线程运行对象
    PRUNNABLE_FUNC pRunFunc;    //线程执行的任务
    void *arg;
};
class CAbstractRunnable
{
public:
    #define REGIST_RUN_FUNC(ClassName, FuncName) \
        static void* STATIC_##FuncName(void *lParam){ \
            struct SThreadInfo *pThreadInfo = (struct SThreadInfo*)lParam; \
            ClassName *p = (ClassName*)pThreadInfo->pRunObj; \
            return p->FuncName(pThreadInfo); \
        }

    #define GET_RUN_FUNC(FuncName) STATIC_##FuncName

    bool bShouldStop;
    int sleepInterval;

    CAbstractRunnable();

    virtual std::string& getObjectName() = 0;
    int isShouldStop();
    void setShouldStop(int bShouldStop);
    int isRunning();
    void startThread();
    void stopThread();
    void idleProcess();
};

class CThreadUtils
{
private:
    static std::vector<struct SThreadInfo*> ThreadInfoList;
public:
    static int createThreadOnCore(CAbstractRunnable *pObject, PRUNNABLE_FUNC pFunc, int coreId, int bWatch, void *arg=NULL);
    static int restartThread(struct SThreadInfo *pThreadInfo);
    static void watcher();
    static void startWatcherThread();
    static void sleep(unsigned int ms);
    static int setPriority(unsigned int value, int type);
    static int showPriority();
    static int setThreadAffinityMask(unsigned int pid);
    static int getCpuNum();
    static int isObjRunning(CAbstractRunnable *pObj);
    static void startObj(CAbstractRunnable *pObj);
    static void stopObj(CAbstractRunnable *pObj);
    static void stopAll();
};
typedef CThreadUtils ThreadUtils;


#endif

threadutils.cpp

#include "threadutils.h"
#ifndef WIN32
#include <signal.h>
#endif


std::vector<struct SThreadInfo*> CThreadUtils::ThreadInfoList;

#ifndef WIN32
void *ThreadMain(void *lpParam)
#else
DWORD __stdcall ThreadMain(void *lpParam)
#endif
{
    struct SThreadInfo *pa = (struct SThreadInfo *)lpParam;
    if(pa->coreId!=-1)
        CThreadUtils::setThreadAffinityMask(pa->coreId);
    pa->bRunning = 1;
    pa->pRunObj->bShouldStop = 0;
    pa->pRunFunc(lpParam);
    pa->bRunning = 0;
    return 0;
}

CAbstractRunnable::CAbstractRunnable()
{
    bShouldStop = true;
    sleepInterval = 10;
}

int CAbstractRunnable::isShouldStop()
{
    return bShouldStop;
}

int CAbstractRunnable::isRunning()
{
    return CThreadUtils::isObjRunning(this);
}

void CAbstractRunnable::startThread()
{
    CThreadUtils::startObj(this);
}

void CAbstractRunnable::stopThread()
{
    CThreadUtils::stopObj(this);
}

void CAbstractRunnable::setShouldStop(int bShouldStop)
{
    this->bShouldStop = bShouldStop;
}

void CAbstractRunnable::idleProcess()
{
    CThreadUtils::sleep(sleepInterval);
}

//启动线程
int CThreadUtils::createThreadOnCore(CAbstractRunnable *pRunObj,
            PRUNNABLE_FUNC pFunc,
            int coreId,
            int bWatch,
            void *arg)
{
    SThreadInfo *pThreadInfo = new SThreadInfo();
    pThreadInfo->bRunning = 0;
    pThreadInfo->bWatch = bWatch;
    pThreadInfo->coreId = coreId;
    pThreadInfo->pRunObj = pRunObj;
    pThreadInfo->pRunFunc = pFunc;
    pThreadInfo->arg = arg;

#ifdef WIN32
    pThreadInfo->hThread = CreateThread(
        NULL,       // no security attributes 
        0,          // use default stack size  
        ThreadMain, // thread function 
        (LPVOID)pThreadInfo,    // argument to thread function ,this object pointer
        0,          //CREATE_SUSPENDED, // use default creation flags 
        NULL);      // returns the thread identifier
    if (pThreadInfo->hThread == NULL)
    {
        printf("createThreadOnCore failured, object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        return -1;
    }
    return 0;
#else
    int iRet;
    iRet = pthread_create(
        &pThreadInfo->hThread,      //thread id
        NULL,           //thread attr
        ThreadMain,     //thread function 
        (void *)pThreadInfo);   //argumet to thread function ,this object pointer
    if (iRet != 0 )
    {
        printf("createThreadOnCore failured object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        delete pThreadInfo;
        return -1;
    }
    else
    {
        printf("createThreadOnCore success object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        ThreadInfoList.push_back(pThreadInfo);
        return 0;
    }
#endif
}

//重启线程
int CThreadUtils::restartThread(struct SThreadInfo *pThreadInfo)
{
#ifdef WIN32
    pThreadInfo->hThread = CreateThread(
        NULL,       // no security attributes 
        0,          // use default stack size  
        ThreadMain, // thread function 
        (LPVOID)pThreadInfo,    // argument to thread function ,this object pointer
        0,          //CREATE_SUSPENDED, // use default creation flags 
        NULL);      // returns the thread identifier
    if (pThreadInfo->hThread == NULL)
    {
        printf("restartThreadOnCore failured object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        return -1;
    }
    return 0;
#else
    int iRet;
    iRet = pthread_create(
        &pThreadInfo->hThread,      //thread id
        NULL,           //thread attr
        ThreadMain,     //thread function 
        (void *)pThreadInfo);   //argumet to thread function ,this object pointer
    if (iRet != 0 )
    {
        printf("restartThreadOnCore failure object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        return -1;
    }
    else
    {
        printf("restartThreadOnCore success object=%s core=%d\n",
            pThreadInfo->pRunObj->getObjectName().c_str(), pThreadInfo->coreId);
        return 0;
    }
#endif
}

//线程看护
void CThreadUtils::watcher()
{
    std::vector<SThreadInfo*>::iterator it;

    while(1)
    {
        for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
        {
            if(!(*it)->bWatch)
                continue;
            if((*it)->pRunObj->bShouldStop)
                continue;
#ifdef WIN32
            DWORD ExitCode;
            if(!GetExitCodeThread((*it)->hThread, &ExitCode)) continue;
            if(ExitCode != STILL_ACTIVE)
#else
            if( pthread_kill((*it)->hThread,0) == ESRCH )
#endif
            {
                (*it)->bRunning = 0;
                printf("Thread %s was exit on core %d, restart now\n",
                    (*it)->pRunObj->getObjectName().c_str(), (*it)->coreId);
                CThreadUtils::restartThread(*it);
                CThreadUtils::sleep(1);
            }
        }
        CThreadUtils::sleep(5000);
    }
}

//启看护线程
#ifdef WIN32
void CThreadUtils::startWatcherThread()
{
    HANDLE hd = CreateThread(
        NULL,       // no security attributes 
        0,          // use default stack size  
        (DWORD(__stdcall*)(void*))CThreadUtils::watcher,    // thread function 
        NULL,   // argument to thread function ,this object pointer
        0,          //CREATE_SUSPENDED, // use default creation flags 
        NULL);      // returns the thread identifier
    if (hd == NULL)
    {
        printf("can not create thread watcher thread\n");
        return;
    }
}
#else
void CThreadUtils::startWatcherThread()
{
    pthread_t pid;
    if(0!=pthread_create(&pid, NULL, (void*(*)(void*))CThreadUtils::watcher, NULL))
    {
        printf("can not create thread watcher thread\n");
        return;
    }
}
#endif

void CThreadUtils::sleep(unsigned int ms)
{
#ifdef WIN32
    Sleep(ms);
#else
    ms *=1000;
    usleep(ms);
#endif
}

//设置线程优先级
int CThreadUtils::setPriority(unsigned int value, int type)
{
#ifdef WIN32
    u_int32_t priority = THREAD_PRIORITY_NORMAL;
    if(value == THREADUTILS_PRIORITY_LOW)
        priority = THREAD_PRIORITY_LOWEST;
    else if(value == THREADUTILS_PRIORITY_HIGH)
        priority = THREAD_PRIORITY_HIGHEST;
    int bSucc = SetThreadPriority(GetCurrentThread(), priority);
    if(!bSucc)
    {
        return -1;
    }
#else
    int rs;
    /*SCHED_FIFO优先级策略 */
    struct sched_param param;
    if(value == THREADUTILS_PRIORITY_LOW)
        param.__sched_priority = sched_get_priority_min(type);//(SCHED_FIFO/*SCHED_RR*/);
    else if(value == THREADUTILS_PRIORITY_HIGH)
        param.__sched_priority = sched_get_priority_max(type);//(SCHED_FIFO/*SCHED_RR*/);
    else
        param.__sched_priority = (sched_get_priority_min(type)+sched_get_priority_max(type))/2;

    rs = sched_setscheduler(0, type,&param);
    if(rs != 0 )
    {
        return -1;
    }
#endif
    return 0;
}

//查询线程优先级
int CThreadUtils::showPriority()
{
#ifdef WIN32
    int level;
    level = GetThreadPriority(GetCurrentThread());
    printf("policy level:%d\n",GetThreadPriority(GetCurrentThread()));
    return level;
#else
    int policy, ret;
    struct sched_param param;
    ret = pthread_getschedparam(pthread_self(), &policy, &param);
    if(ret!=0)
        perror("pthread_getschedparam:");
    else
    {
        if (policy == SCHED_FIFO)
            printf("policy:SCHED_FIFO, ");
        else if (policy == SCHED_OTHER)
            printf("policy:SCHED_OTHER, ");
        else if (policy == SCHED_RR)
            printf("policy:SCHED_RR, ");
        else printf("policy: UNKNOW, ");
            printf("policy level:%d\n", param.sched_priority);
    }
    return ret;
#endif
}

//绑定cpu逻辑核
int CThreadUtils::setThreadAffinityMask(unsigned int pid)
{
#ifdef WIN32
    u_int32_t val = 1 << pid;
    u_int32_t hr= SetThreadAffinityMask(GetCurrentThread(), val);
    if(hr == 0)
    {
        printf("setThreadAffinityMask %u failure\n", val);
        return -1;
    }
#else
    // CPU binding in linux, pid=0 express to bind current thread
    int ret;
    cpu_set_t mask;
    CPU_ZERO(&mask);
    int len = sizeof(mask);
    ret = sched_getaffinity(0, len, &mask);
    if (ret == -1)
    {
        printf("sched_getafinity failed!\n");
        return -1;
    }

    CPU_ZERO(&mask);
    CPU_SET(pid, &mask);
    ret = sched_setaffinity(0, len, &mask);
    if (ret == -1)
    {
        printf("sched_setaffinity failed!\n");
        return -1;
    }
#endif
    return 0;
}

//获取逻辑核个数
int CThreadUtils::getCpuNum()
{
    int cpuNum = 0;

#ifdef WIN32
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    cpuNum = sysInfo.dwNumberOfProcessors;
#else
    cpuNum = sysconf(_SC_NPROCESSORS_ONLN);
#endif

    return cpuNum;
}

int CThreadUtils::isObjRunning(CAbstractRunnable *pObj)
{
    std::vector<SThreadInfo*>::iterator it;

    printf("start thread object=%s...\n", pObj->getObjectName().c_str());

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
        if( (*it)->pRunObj != pObj )
            continue;
        if((*it)->bRunning)
            return 1;
    }

    return 0;
}

//启动某对象所有线程
void CThreadUtils::startObj(CAbstractRunnable *pObj)
{
    std::vector<SThreadInfo*>::iterator it;

    printf("start thread object=%s...\n", pObj->getObjectName().c_str());

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
        if( (*it)->pRunObj != pObj )
            continue;
        if((*it)->bRunning)
        {
            printf("one thread is already running, can not restart\n");
            continue;
        }
        restartThread(*it);
        sleep(1);
    }
}

//结束某对象线程
void CThreadUtils::stopObj(CAbstractRunnable *pObj)
{
    std::vector<SThreadInfo*>::iterator it;

    printf("stop thread object=%s...\n", pObj->getObjectName().c_str());

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
        if( (*it)->pRunObj != pObj )
            continue;
        (*it)->pRunObj->bShouldStop = 1;
        break;
    }

    sleep(2000);

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
        if( (*it)->pRunObj != pObj )
            continue;
#ifdef WIN32
        DWORD dwExitCode = 0;
        TerminateThread((*it)->hThread, dwExitCode);
#else
        pthread_cancel((*it)->hThread);
#endif
        (*it)->bRunning = 0;
    }
}

//结束所有线程
void CThreadUtils::stopAll()
{
    std::vector<SThreadInfo*>::iterator it;

    printf("stop all thread...\n");

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
        (*it)->pRunObj->bShouldStop = 1;
    }

    sleep(2000);

    for(it=ThreadInfoList.begin(); it!=ThreadInfoList.end(); it++)
    {
#ifdef WIN32
        DWORD dwExitCode = 0;
        TerminateThread((*it)->hThread, dwExitCode);
#else
        pthread_cancel((*it)->hThread);
#endif
        (*it)->bRunning = 0;
    }
    sleep(1000);

    int i;
    for(i=0; i<ThreadInfoList.size(); i++)
    {
        if(ThreadInfoList[i])
        {
            delete ThreadInfoList[i];
            ThreadInfoList[i] = NULL;
        }
    }
    ThreadInfoList.clear();
}


/***

class A : public CAbstractRunnable
{
public:
    void *run1(struct SThreadInfo *pThreadInfo);
    void *run2(struct SThreadInfo *pThreadInfo);
    REGIST_RUN_FUNC(A,run1)
    REGIST_RUN_FUNC(A,run2)
};

class B : public CAbstractRunnable
{
public:
    void *run1(struct SThreadInfo *pThreadInfo);
    void *run2(struct SThreadInfo *pThreadInfo);
    REGIST_RUN_FUNC(B,run1)
    REGIST_RUN_FUNC(B,run2)
};

void * A::run1(struct SThreadInfo *pThreadInfo)
{
    printf("A::runn1() is running...\n");
    sleep(15);
}

void * A::run2(struct SThreadInfo *pThreadInfo)
{
    printf("A::runn2() is running...\n");
    sleep(10);
}

void * B::run1(struct SThreadInfo *pThreadInfo)
{
    printf("B::runn1() is running...\n");
    sleep(20);
}

void * B::run2(struct SThreadInfo *pThreadInfo)
{
    printf("B::runn2() is running...\n");
    sleep(20);
}

int main()
{
    A a;
    B b;
    A *pa;
    pa = &a;
    
    CThreadUtils::createThreadOnCore(&a, a.GET_RUN_FUNC(run1), 0, 1);usleep(100000);
    CThreadUtils::createThreadOnCore(&a, a.GET_RUN_FUNC(run2), 1, 1);usleep(100000);
    CThreadUtils::createThreadOnCore(&b, b.GET_RUN_FUNC(run1), 2, 1);usleep(100000);
    CThreadUtils::createThreadOnCore(&b, b.GET_RUN_FUNC(run2), 3, 1);usleep(100000);
    CThreadUtils::createThreadOnCore(pa, pa->GET_RUN_FUNC(run1), 4, 1);usleep(100000);

    //CThreadUtils::watcher();
    CThreadUtils::startWatcherThread();

    while(1) sleep(1);
    
    return 0;
}
***/

不绑cpu,简单的线程封装
threadutl.h

#ifndef _CTHREAD_H
#define _CTHREAD_H

#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

class CZthread
{
public:
    CZthread();
    virtual ~CZthread();
    int mutexInit(pthread_mutex_t* mutexlock);
    int mutexLock(pthread_mutex_t* mutexlock);
    int mutexUnlock(pthread_mutex_t* mutexlock);
    int mutexDestroy(pthread_mutex_t* mutexlock);
    //int getThreadNumber(void);
    //void setThreadNumber(int threadNumber);
    pthread_t start();
    virtual void run() = 0;
    void stop();
protected:
    bool bRun;
    //int m_threadNumber;
    //pthread_mutex_t m_mutex;
};

#endif

threadutl.cpp

#include "zthread.h"

CZthread::CZthread()
{
    bRun = true;
    //m_threadNumber = 1;
}

CZthread::~CZthread()
{
    stop();
}

static void* actionRun(void* param)
{
    CZthread* pt = (CZthread*)param;
    pt->run();
    return NULL;
}

int CZthread::mutexInit(pthread_mutex_t* mutexlock)
{
    return pthread_mutex_init(mutexlock, NULL);
}

int CZthread::mutexLock(pthread_mutex_t* mutexlock)
{
    return pthread_mutex_lock(mutexlock);
}

int CZthread::mutexUnlock(pthread_mutex_t* mutexlock)
{
    return pthread_mutex_unlock(mutexlock);
}

int CZthread::mutexDestroy(pthread_mutex_t* mutexlock)
{
    return pthread_mutex_destroy(mutexlock);
}

#if 0
int CZthread::getThreadNumber(void)
{
    return this->m_threadNumber;
}

void CZthread::setThreadNumber(int threadNumber)
{
    this->m_threadNumber = threadNumber;
}
#endif

pthread_t CZthread::start()
{
#if 1
    pthread_t id;
    if (pthread_create(&id, NULL, actionRun, this) != 0)
        std::cerr << "线程创建失败,线程号=" << id << std::endl;

    return id;
#endif
#if 0
    pthread_t pthread[this->m_threadNumber];
    for (int i = 1; i <= this->m_threadNumber; i++)
    {
        if (pthread_create(&pthread[i], NULL, actionRun, this) != 0)
        {
            std::cerr << "线程创建失败,线程号=" << i << std::endl;
        }
    }

    for (int i = 1; i <= this->m_threadNumber; i++)
    {
        if (pthread_join(pthread[i], NULL) != 0)
        {
            std::cerr << "线程执行失败,线程号=" << i << std::endl;
        }
    }
#endif
}

void CZthread::stop()
{
    bRun = false;
}

test.cpp

#include "threadutl.h"
#include <string.h>
#include <iostream>
class CTest : public CZthread
{
public:
    CTest() { inum = 10; }
    void run()
    {
        for (int i = 0; i < inum; i++)
        {
            std::cout << i << std::endl;
        }
    }
private:
    int inum;
};

int main(int argc, char** argv)
{
    std::string strmd5;
    //CContentCheck::instance()->getFileMd5("./bin/ftpdir/tn.mp3", strmd5);
    CTest *ts = new CTest();
    ts->setThreadNumber(2);
    ts->start();

    int i;
    while(i < 10000)
        i++;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值