Linux C++线程池
這是對pthread線程的一個簡單應用
1.??????實現了線程池的概念,線程可以重復使用。
2.??????對信號量,互斥鎖等進行封裝,業務處理函數中只需寫和業務相關的代碼。
3.??????移植性好。如果想把這個線程池代碼應用到自己的實現中去,只要寫自己的業務處理函數和改寫工作隊列數據的處理方法就可以了。
?
Sample代碼主要包括一個主程序和兩個線程實現類
ThreadTest.cpp:主程序
CThreadManager:線程管理Class,線程池的實現類
CThread:線程Class.
主程序實現方法。
1.??????實現main函數和一個需要線程處理的業務函數(例子代碼中業務函數是一個簡單的計算函數Count)。在main函數中創建CThreadManager的實例,產生線程池。這個時候,把業務函數作為函數指針傳到CThreadManager里面,最終會被線程調用。
2.??????向工作隊列中放入業務函數要處理的數據。
3.??????設置信號量,喚醒線程。
CODE:
1?//?線程要執行的函數
?2?int?Count(int?nWork)
?3?{
?4?????int?nResult?=?nWork?*?nWork;
?5?????printf("count?result?is?%d\n",nResult);
?6?
?7?????return?0;
?8?}
?9?
10?int?main()?{
11?
12?????//?創建線程管理類的實例,把要執行的線程函數和最大線程數傳進去
13?????CThreadManager*?pManager?=?new?CThreadManager(Count,?3);
14?
15?????//?把要進行計算的數放到工作隊列中
16?????pManager->PushWorkQue(5);
17?????pManager->PushWorkQue(20);
18?
19?????//?設置信號量,喚醒線程
20?????pManager->PostSem();
21?????pManager->PostSem();
22?
23?????//?等待子線程執行
24?????sleep(1);
25?
26?????return?0;
27?}
CThreadManager實現的方法
1.?把信號量和互斥鎖等封裝成自己的函數
2.?在new方法里,循環調用CThread的new方法,啟動一定數量(可設定)的線程,產生線程池。
3.?這些線程啟動后,就會執行CThreadManager中的ManageFuction函數。這個函數是無限循環的,保證了線程在整個程序的生命周期中不銷毀。
4.?在循環處理里面,第一行代碼就是等待一個信號量,這個信號量是由主程序進行設置的,這個信號信號量如果沒有被設置(代表暫時沒有需要處理的工作),所有線程都在這里阻塞著。
4.??????一旦信號量被設置,根據Linux線程調度機制,在阻塞的線程隊列中,其中一個線程被喚醒,可以執行后面的代碼。
5.??????從工作隊列中取出要進行處理的數據(使用互斥鎖進行排他)
6.??????通過函數指針調用main函數傳過來的業務函數,處理數據。
7.??????業務函數執行完之后,線程進入下一個循環,等待新的信號量。
class?CThreadManager?{
????friend?void*?ManageFuction(void*);
private:
????sem_t?m_sem;????//?信號量
????pthread_mutex_t?m_mutex;?//?互斥鎖
????queue<int>?m_queWork;?//?工作隊列
????list<CThread*>?m_lstThread;?//?線程list
????int?(*m_threadFuction)(int);?//函數指針,指向main函數傳過來的線程執行函數
public:
????CThreadManager(int?(*threadFuction)(int),?int?nMaxThreadCnt);
????virtual?~CThreadManager();
????int?WaitSem();
????int?PostSem();
????int?LockMutex();
????int?UnlockMutex();
????void?PushWorkQue(int?nWork);
????int?PopWorkQue();
????int?RunThreadFunction(int?nWork);
};
//?線程執行函數,它只是個殼子,處理信號量和互斥鎖等,
//?最后調用main函數傳過來的線程執行函數來實現業務處理
void*?ManageFuction(void*?argv)
{
????CThreadManager*?pManager?=?(CThreadManager*)argv;
????//?進行無限循環(意味著線程是不銷毀的,重復利用)
????while(true)
????{
????????//?線程開啟后,就在這里阻塞著,直到main函數設置了信號量
????????pManager->WaitSem();
????????printf("thread?wakeup.\n");
????????//?從工作隊列中取出要處理的數
????????pManager->LockMutex();
????????int?nWork?=?pManager->PopWorkQue();
????????pManager->UnlockMutex();
????????printf("call?Count?function.\n");
????????pManager->RunThreadFunction(nWork);
????}
????return?0;
}
CThreadManager::CThreadManager(int?(*threadFuction)(int),?int?nMaxThreadCnt)? {
????sem_init(&m_sem,?0,?0);
????pthread_mutex_init(&m_mutex,?NULL);
????m_threadFuction?=?threadFuction;
????for(int?i=0;?i<nMaxThreadCnt;?i++)
????{
????????CThread*?pThread?=?new?CThread(ManageFuction,?this);
????????printf("thread?started.\n");
????????m_lstThread.push_back(pThread);
????}
}
CThread實現的方法
CThreadManager比較簡單,封裝了創建線程和join線程的函數。
CThread::CThread(void*?(*threadFuction)(void*),void*?threadArgv)?
{????//?初始化線程屬性
????pthread_attr_t?threadAttr;
????pthread_attr_init(&threadAttr);
????pthread_create(&m_thread,?&threadAttr,?threadFuction,?threadArgv);
}
總結
以上是生活随笔為你收集整理的Linux C++线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下C++的多线程编程---(转
- 下一篇: linux 其他常用命令