绑定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,¶m);
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, ¶m);
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;
}