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