C/C++ pthread 线程库的封装
經常沒事寫一些服務器壓力測試的工具,如http,mysql,等。說到壓力測試,首先想到的應該就是多線程,研究過一段時間的pthread,包括線程鎖,在這里發一個自己寫的Posix封裝,可用于很多需要使用到多線程的情景當中。
Posix.h
Posix應該把它當成一個父類,寫一個子類繼承他,并重寫action方法,action()為所有的線程所執行的內容,最后使用Run()開始執行所有線程。
#ifndef?POSIX_H_ #define?POSIX_H_#include?<iostream> #include?<pthread.h> #include?<unistd.h> #include?<stdlib.h>using?namespace?std;class?Posix?{ public:Posix();int?getThreadNumber(void);??//獲取線程數int?pthreadMutexInit(void);??//初始化線程鎖,如果不希望使用鎖可以不用,有關鎖的更多,在后面介紹int?pthreadMutexLock(void);??//加鎖int?pthreadMutexUnlock(void);?//解鎖int?pthreadMutexDestroy(void);?//銷毀鎖void?setThreadNumber(int?threadNumber);?//設置開啟的線程數void?Run();????????????????????//所有線程開始執行virtual?void?action()=0;????????//每個線程執行的內容,在子類中重寫 protected:/*線程數*/int?_threadNumber;/*線程鎖*/pthread_mutex_t?_mutex; };#endif?/*?POSIX_H_?*/Posix.cpp
因為pthread_create()函數只接收函數指針,不接受C++成員函數,所以另外創建靜態函數actionRun()作為橋接。
#include?"Posix.h"Posix::Posix(){//初始化線程數為8_threadNumber?=?8; }static?void*?actionRun(void*?parm){Posix*?pt?=?(Posix*)parm;pt->action();????//執行子類重寫的虛函數return?NULL; }/*線程鎖初始化函數*/ int?Posix::pthreadMutexInit(void){return?pthread_mutex_init(&this->_mutex,NULL); }/*線程加鎖*/ int?Posix::pthreadMutexLock(void){return?pthread_mutex_lock(&this->_mutex); }/*線程解鎖*/ int?Posix::pthreadMutexUnlock(void){return?pthread_mutex_unlock(&this->_mutex); }/*銷毀鎖*/ int?Posix::pthreadMutexDestroy(void){return?pthread_mutex_destroy(&this->_mutex); }int?Posix::getThreadNumber(void){return?this->_threadNumber; } void?Posix::setThreadNumber(int?threadNumber){this->_threadNumber?=?threadNumber; }void?Posix::Run(){pthread_t?pthread[this->_threadNumber];?//線程數組for?(?int?count?=?1?;?count?<=?this->_threadNumber?;?count++?){?//開始創建線程//在此,因為pthread_create的第三個參數只接收函數指針,C++成員函數不能進行傳遞,所以創建actionRun為普通的靜態函數,作為橋接,具體實現請往上看actionRun();if?(?pthread_create(?&pthread[count]?,?NULL?,?actionRun?,?this)?!=?0?){cerr?<<?"線程創建失敗,線程號?=?"?<<?count?<<endl;}}for?(?int?count?=?1?;?count?<=?this->_threadNumber?;?count++?){if?(?pthread_join(?pthread[count],?NULL?)?!=?0?){cerr?<<?"線程執行失敗,線程號?=?"?<<?count?<<?endl;}} // cout?<<?"線程執行完成!"?<<?endl; }上面是Posix父類的定義與實現,下面我們寫一個新的test類來繼承Posix類
test.h
重寫父類action()函數,把要做的事寫上,這里我們打印每個線程的ID
#ifndef?TEST_H_ #define?TEST_H_#include?"Posix.h"class?test?:?public?Posix?{ public:action(){cout?<<?pthread_self()?<<?endl;?//打印線程ID} }#endif?/*?TEST_H_?*/下面是main.cpp
#include?"test.h" int?main(void){test*?mytest?=?new?test();mytest->setThreadNumber(10);?//設置線程數為10mytest->Run();return?0; }執行結果:
下面是有關線程鎖的介紹。
在線程執行時,所有的線程是并發執行的,我們不希望線程之間搶占同一資源,如多個線程對同一個FILE指針進行寫操作,這樣會出現莫名其妙的問題,這時我們就要使用線程鎖,所以在main.cpp中我們用pthreadMutexInit()方法來初始化一下線程鎖
#include?<iostream> #include?"test.h"using?namespace?std;int?main(void){test*?mytest?=?new?test();mytest->pthreadMutexInit();?//初始化鎖mytest->setThreadNumber(10);mytest->Run();mytest->pthreadMutexDestroy();?//銷毀鎖return?0; }同樣的,在每個線程執行的過程當中,當進行到某個步驟的時候,我們也可以為其設置加鎖和解鎖,例如所有線程需要對一個成員變量進行操作時,我們可以在其操作之前加鎖,操作完成后解鎖。
#ifndef?TEST_H_ #define?TEST_H_#include?"Posix.h"class?test?:?public?Posix?{ public:test();virtual?~test();void?action(){this->pthreadMutexLock();????//鎖住線程,形成隊列,先到的先執行cout?<<?pthread_self()?<<?endl;?//打印線程IDthis->pthreadMutexUnlock();??//解鎖線程} };#endif?/*?TEST_H_?*/最后編譯時別忘了添加編譯選項: -lpthread
轉載于:https://blog.51cto.com/xzx951753/1716088
總結
以上是生活随笔為你收集整理的C/C++ pthread 线程库的封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开机自启
- 下一篇: 安装部署gitlab ci