新聞中心
隨著計(jì)算機(jī)性能的不斷提高和軟件系統(tǒng)的復(fù)雜化,單線程運(yùn)行程序已經(jīng)無(wú)法滿足程序的執(zhí)行效率。多線程并行運(yùn)行可以有效利用現(xiàn)代多核處理器的計(jì)算能力,提高系統(tǒng)運(yùn)行效率。Linux是一個(gè)支持多線程處理的操作系統(tǒng),本文將介紹如何利用Linux多線程機(jī)制實(shí)現(xiàn)并行運(yùn)行,從而提高系統(tǒng)運(yùn)行效率。

成都創(chuàng)新互聯(lián)長(zhǎng)期為成百上千客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為洛川企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),洛川網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
一、多線程并行運(yùn)行的優(yōu)勢(shì)
多線程并行運(yùn)行優(yōu)化了程序執(zhí)行過(guò)程中的資源利用率,同時(shí),在多線程并行執(zhí)行的過(guò)程中,多個(gè)線程可以同時(shí)進(jìn)行多個(gè)任務(wù),從而減少了等待時(shí)間。這種優(yōu)化效果尤其在計(jì)算密集型任務(wù)中得到體現(xiàn)。在單線程任務(wù)中,當(dāng)軟件系統(tǒng)出現(xiàn)IO等待時(shí),CPU空閑,造成系統(tǒng)資源的浪費(fèi);而多線程并行執(zhí)行可以在一個(gè)線程IO等待的時(shí)候,讓其他的線程繼續(xù)執(zhí)行任務(wù),從而充分利用系統(tǒng)資源,提高系統(tǒng)的運(yùn)行效率。另外,多線程并行運(yùn)行可以提高程序的響應(yīng)效率和處理速度。由于多線程并行運(yùn)行可以同時(shí)執(zhí)行多個(gè)任務(wù),所以在一些需要同時(shí)處理多個(gè)請(qǐng)求的場(chǎng)景中可以得到越來(lái)越廣泛的應(yīng)用。
二、Linux多線程并發(fā)模型
Linux采用POSIX線程作為多線程并發(fā)模型,通過(guò)創(chuàng)建多個(gè)線程并發(fā)執(zhí)行任務(wù)。線程是一個(gè)比進(jìn)程更小粒度的執(zhí)行單元。Linux系統(tǒng)中的線程與進(jìn)程的主要區(qū)別在于,進(jìn)程是將資源獨(dú)立地劃分給不同的程序,而線程是在同一個(gè)程序享資源,并發(fā)執(zhí)行。線程可以共享大部分進(jìn)程的地址空間,例如數(shù)據(jù)和代碼段,因此,線程間通信更加方便,具有更高的性能。
三、多線程的創(chuàng)建與管理
多線程的創(chuàng)建需要調(diào)用pthread_create函數(shù),該函數(shù)創(chuàng)建新線程并指定線程執(zhí)行函數(shù),即在多線程中要執(zhí)行的任務(wù)。其函數(shù)原型如下:
int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
其中,thread參數(shù)返回新線程ID,attr參數(shù)用于設(shè)置線程屬性,一般設(shè)置為NULL即可,默認(rèn)屬性,start_routine參數(shù)是執(zhí)行線程的函數(shù),arg參數(shù)是傳遞給線程的參數(shù)。
線程的退出由自身完成,使用pthread_exit函數(shù)退出線程:
void pthread_exit (void *retval);
該函數(shù)終止正在調(diào)用的線程,并將retval指定的值傳遞給線程創(chuàng)建者。
pthread_join函數(shù)可以等待指定線程的結(jié)束,并在指定的線程結(jié)束后返回,釋放線程資源。如果一些線程必須在其他線程結(jié)束時(shí)才能繼續(xù)執(zhí)行,則需要使用pthread_join函數(shù)。函數(shù)原型如下:
int pthread_join (pthread_t thread, void **retval);
其中,thread參數(shù)為等待的線程ID,retval參數(shù)返回線程的退出狀態(tài)。
四、多線程的同步
多個(gè)線程并發(fā)執(zhí)行時(shí),訪問(wèn)共享資源,可能產(chǎn)生數(shù)據(jù)競(jìng)爭(zhēng)和死鎖等問(wèn)題。為了解決這些問(wèn)題,Linux提供了多種線程同步機(jī)制。
1. 互斥鎖:用于同步不同線程之間對(duì)共享資源的訪問(wèn),是最常用的同步機(jī)制。當(dāng)一個(gè)線程占用互斥鎖時(shí),其它線程必須等待,直到占用互斥鎖的線程釋放鎖。主要用于線程間訪問(wèn)共享數(shù)據(jù)的互斥保護(hù)。
2. 讀寫鎖:多個(gè)線程可以同時(shí)讀共享資源,該鎖適用于即可以讀也可以寫的情況。當(dāng)一個(gè)線程請(qǐng)求寫入共享資源時(shí),其它線程必須等待,直到寫者完成工作。但是,讀者可同時(shí)訪問(wèn)共享資源。
3. 條件變量:用于線程之間的通信和同步,用于等待某個(gè)事件的發(fā)生。
五、多線程示例
下面是一個(gè)簡(jiǎn)單的使用多線程的示例程序:
#include
#include
#include
void *thread_function(void *arg);
int mn(int argc, char *argv[])
{
pthread_t my_thread;
int status;
if (pthread_create(&my_thread, NULL, thread_function, NULL))
{
printf(“error creating thread.”);
exit(EXIT_FLURE);
}
printf(“Thread created successfully.\n”);
status = pthread_join(my_thread, NULL);
if (status != 0)
{
printf(“ERROR; return code from pthread_join()”);
exit(EXIT_FLURE);
}
printf(“Thread exited successfully.\n”);
return 0;
}
void *thread_function(void *arg)
{
printf(“Thread function is called.\n”);
pthread_exit(NULL);
}
該示例中,pthread_create函數(shù)創(chuàng)建新線程,并調(diào)用thread_function函數(shù)執(zhí)行任務(wù)。該函數(shù)負(fù)責(zé)輸出一條消息,并在最后使用pthread_exit退出線程。在主函數(shù)中,使用pthread_join等待線程結(jié)束,并釋放線程資源。
六、
相關(guān)問(wèn)題拓展閱讀:
- Linux C++多線程同步的四種方式
- linux操作系統(tǒng)多進(jìn)程和多線程的區(qū)別
Linux C++多線程同步的四種方式
From :
1.同一個(gè)線程內(nèi)部,指令按照先后順序執(zhí)行;但不同線程之間的指令很難說(shuō)清楚是哪一個(gè)先執(zhí)行,在并況下,指令執(zhí)行的先后順序由內(nèi)核決定。
如果運(yùn)行的結(jié)果依賴于不同線程執(zhí)行的先后的話,那么就會(huì)形成競(jìng)爭(zhēng)條件,在這樣的情況下,計(jì)算的結(jié)果很難預(yù)知,所以應(yīng)該盡量避免競(jìng)爭(zhēng)條件的形成。
2.最常見(jiàn)的解決競(jìng)爭(zhēng)條件的方法是:將原先分離的兩個(gè)指令構(gòu)成一個(gè)不可分割的原子操作,而其他任務(wù)不能插入到原子操作中!
3.對(duì)
多線程
來(lái)說(shuō),同步指的是在一定時(shí)間內(nèi)只允許某一個(gè)線程訪問(wèn)某個(gè)資源,而在此時(shí)間內(nèi),不允許其他線程訪問(wèn)該資源!
互斥鎖
條件變量
讀寫鎖
信號(hào)量
一種特殊的
全局變量
,擁有l(wèi)ock和unlock兩種狀態(tài)。
unlock的互斥鎖可以由某個(gè)線程獲得,一旦獲得,這個(gè)互斥鎖會(huì)鎖上變成lock狀態(tài),此后只有該線程由權(quán)力打開(kāi)該鎖,其他線程想要獲得互斥鎖,必須得到互斥鎖再次被打開(kāi)之后。
1.互斥鎖的初始化, 分為靜態(tài)初始化和動(dòng)態(tài)初始化.
2.互斥鎖的相關(guān)屬性及分類
(1) attr表示互斥鎖的屬性;
(2) pshared表示互斥鎖的共享屬性,由兩種取值:
1)PTHREAD_PROCESS_PRIVATE:鎖只能用于一個(gè)進(jìn)程內(nèi)部的兩個(gè)線程進(jìn)行互斥(默認(rèn)情況)
2)PTHREAD_PROCESS_SHARED:鎖可用于兩個(gè)不同進(jìn)程中的線程進(jìn)行互斥,使用時(shí)還需要在進(jìn)程共享內(nèi)存中分配互斥鎖,然后為該互斥鎖指定屬性就可以了。
互斥鎖存在缺點(diǎn):
(1)某個(gè)線程正在等待共享數(shù)據(jù)內(nèi)某個(gè)條件出現(xiàn)。
(2)重復(fù)對(duì)數(shù)據(jù)對(duì)象加鎖和解鎖(輪詢),但是這樣輪詢非常耗費(fèi)時(shí)間和資源,而且效率非常低,所以互斥鎖不太適合這種情況。
當(dāng)線程在等待滿足某些條件時(shí),使線程進(jìn)入睡眠狀態(tài);一旦條件滿足,就換線因等待滿足特定條件而睡眠的線程。
程序的效率無(wú)疑會(huì)大大提高。
1)創(chuàng)建
靜態(tài)方式:pthread_cond_t cond PTHREAD_COND_INITIALIZER
動(dòng)態(tài)方式:int pthread_cond_init(&cond,NULL)
Linux thread 實(shí)現(xiàn)的條件變量不支持屬性,所以NULL(cond_attr參數(shù))
2)注銷
int pthread_cond_destory(&cond)
只有沒(méi)有線程在該條件變量上,該條件變量才能注饑畝銷,否則返回EBUSY
因?yàn)長(zhǎng)inux實(shí)現(xiàn)的條件變量沒(méi)有分配什么資源,所以注銷動(dòng)作只包括檢查是否姿肢改有等待線程!(請(qǐng)參考條件變量的底層實(shí)現(xiàn))
3)等待
條件等待:int pthread_cond_wait(&cond,&mutex)
計(jì)時(shí)等待:int pthread_cond_timewait(&cond,&mutex,time)
1.其中計(jì)時(shí)等待如果在給定時(shí)刻前條件沒(méi)有被滿足,則返回ETIMEOUT,結(jié)束等待
2.無(wú)論那種等待方式,都必須有一個(gè)互斥鎖配合,以防止多個(gè)線程同時(shí)請(qǐng)求pthread_cond_wait形成競(jìng)爭(zhēng)條件!
3.在調(diào)用pthread_cond_wait前必須由本線程加鎖
4)激發(fā)
激發(fā)一個(gè)等待線程:pthread_cond_signal(&cond)
激發(fā)所有等待線程:pthread_cond_broadcast(&cond)
重要的是,pthread_cond_signal不會(huì)存在驚群效應(yīng),也就是是它最多給一個(gè)等待線程發(fā)信號(hào),不會(huì)給所有線程發(fā)信號(hào)喚醒,然后要求他們自己去爭(zhēng)搶資源!
pthread_cond_broadcast() 喚醒所有正在pthread_cond_wait()的同一個(gè)條件變量的線程。注意:如果等待的多個(gè)現(xiàn)場(chǎng)不使用同一個(gè)鎖,被喚跡判醒的多個(gè)線程執(zhí)行是并發(fā)的。
pthread_cond_broadcast & pthread_cond_signal
1.讀寫鎖比互斥鎖更加具有適用性和并行性
2.讀寫鎖最適用于對(duì)
數(shù)據(jù)結(jié)構(gòu)
的讀操作讀操作次數(shù)多余寫操作次數(shù)的場(chǎng)合!
3.鎖處于讀模式時(shí)可以線程共享,而鎖處于寫模式時(shí)只能獨(dú)占,所以讀寫鎖又叫做共享-獨(dú)占鎖。
4.讀寫鎖有兩種策略:強(qiáng)讀同步和強(qiáng)寫同步
強(qiáng)讀同步:
總是給讀者更高的優(yōu)先權(quán),只要寫者沒(méi)有進(jìn)行寫操作,讀者就可以獲得訪問(wèn)權(quán)限
強(qiáng)寫同步:
總是給寫者更高的優(yōu)先權(quán),讀者只能等到所有正在等待或者執(zhí)行的寫者完成后才能進(jìn)行讀
1)初始化的銷毀讀寫鎖
靜態(tài)初始化:pthread_rwlock_t rwlock=PTHREAD_RWLOCK_INITIALIZER
動(dòng)態(tài)初始化:int pthread_rwlock_init(rwlock,NULL),NULL代表讀寫鎖采用默認(rèn)屬性
銷毀讀寫鎖:int pthread_rwlock_destory(rwlock)
在釋放某個(gè)讀寫鎖的資源之前,需要先通過(guò)pthread_rwlock_destory函數(shù)對(duì)讀寫鎖進(jìn)行清理。釋放由pthread_rwlock_init函數(shù)分配的資源
如果你想要讀寫鎖使用非默認(rèn)屬性,則attr不能為NULL,得給attr賦值
int pthread_rwlockattr_init(attr),給attr初始化
int pthread_rwlockattr_destory(attr),銷毀attr
2)以寫的方式獲取鎖,以讀的方式獲取鎖,釋放讀寫鎖
int pthread_rwlock_rdlock(rwlock),以讀的方式獲取鎖
int pthread_rwlock_wrlock(rwlock),以寫的方式獲取鎖
int pthread_rwlock_unlock(rwlock),釋放鎖
上面兩個(gè)獲取鎖的方式都是阻塞的函數(shù),也就是說(shuō)獲取不到鎖的話,調(diào)用線程不是立即返回,而是阻塞執(zhí)行,在需要進(jìn)行寫操作的時(shí)候,這種阻塞式獲取鎖的方式是非常不好的,你想一下,我需要進(jìn)行寫操作,不但沒(méi)有獲取到鎖,我還一直在這里等待,大大拖累效率
所以我們應(yīng)該采用非阻塞的方式獲取鎖:
int pthread_rwlock_tryrdlock(rwlock)
int pthread_rwlock_trywrlock(rwlock)
互斥鎖只允許一個(gè)線程進(jìn)入臨界區(qū),而信號(hào)量允許多個(gè)線程進(jìn)入臨界區(qū)。
1)信號(hào)量初始化
int sem_init(&sem,pshared, v)
pshared為0,表示這個(gè)信號(hào)量是當(dāng)前進(jìn)程的局部信號(hào)量。
pshared為1,表示這個(gè)信號(hào)量可以在多個(gè)進(jìn)程之間共享。
v為信號(hào)量的初始值。
返回值
:
成功:0,失?。?1
2)信號(hào)量值的加減
int sem_wait(&sem):以原子操作的方式將信號(hào)量的值減去1
int sem_post(&sem):以原子操作的方式將信號(hào)量的值加上1
3)對(duì)信號(hào)量進(jìn)行清理
int sem_destory(&sem)
linux操作系統(tǒng)多進(jìn)程和多線程的區(qū)別
用ps -eLf 在linux下查看,每一行是一個(gè)進(jìn)程,NLWP列代表這個(gè)進(jìn)程里面有多少個(gè)線程
LWP是輕量級(jí)進(jìn)程的意思
進(jìn)程:運(yùn)行中的程序,–>執(zhí)行過(guò)程稱之為進(jìn)程。
線程:線程是輕量級(jí)的進(jìn)程,是進(jìn)程中的一條執(zhí)行序列,一個(gè)進(jìn)程至少有一條線程。
多線程
優(yōu)點(diǎn):①無(wú)需跨進(jìn)程邊界;②程序邏輯和控制方式簡(jiǎn)單;③所有線程可以直接
共享內(nèi)存
和變量;④線程方式消耗的總資源比進(jìn)程少。
多進(jìn)程優(yōu)點(diǎn):①每個(gè)進(jìn)程相互獨(dú)立,不影響主程序的穩(wěn)定性,子進(jìn)程崩潰沒(méi)關(guān)系;②通過(guò)增加CPU就可以容易擴(kuò)充性能;③可以盡量減少線程加鎖/解鎖的影響,極大提高性能。
多線程缺點(diǎn):①每條線程與主程序共用地址空間,大小受限;②線程之間的同步和加鎖比較麻煩;③一個(gè)線程的崩潰可能影響到整個(gè)程序的穩(wěn)定性;④到達(dá)一定的線程數(shù)之后,即使在增加CPU也無(wú)法提高性能。
多進(jìn)程缺點(diǎn):①邏輯控制復(fù)雜,需要和主程序交互;②需要跨進(jìn)程邊界,如果有大數(shù)據(jù)傳輸,不適合;③多進(jìn)程調(diào)度開(kāi)銷比較大。
Linux系統(tǒng)中多進(jìn)程和多線程的區(qū)別是什么?
1、多進(jìn)程中數(shù)據(jù)共享復(fù)雜、同步簡(jiǎn)單;而多線程中數(shù)據(jù)共享簡(jiǎn)單、同步復(fù)雜。
2、多進(jìn)程占用內(nèi)存多、切換復(fù)雜、速度慢、CPU利用率低;而多線程占用內(nèi)存少、切換簡(jiǎn)單、CPU利用率高。
3、多進(jìn)程的編程簡(jiǎn)單、調(diào)試簡(jiǎn)單;而多線程的編程復(fù)雜、調(diào)試復(fù)雜。
linux多線程是并行運(yùn)行的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux多線程是并行運(yùn)行,Linux多線程實(shí)現(xiàn)并行運(yùn)行,提高系統(tǒng)運(yùn)行效率,Linux C++多線程同步的四種方式,linux操作系統(tǒng)多進(jìn)程和多線程的區(qū)別的信息別忘了在本站進(jìn)行查找喔。
成都網(wǎng)站設(shè)計(jì)制作選創(chuàng)新互聯(lián),專業(yè)網(wǎng)站建設(shè)公司。
成都創(chuàng)新互聯(lián)10余年專注成都高端網(wǎng)站建設(shè)定制開(kāi)發(fā)服務(wù),為客戶提供專業(yè)的成都網(wǎng)站制作,成都網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站設(shè)計(jì)服務(wù);成都創(chuàng)新互聯(lián)服務(wù)內(nèi)容包含成都網(wǎng)站建設(shè),小程序開(kāi)發(fā),營(yíng)銷網(wǎng)站建設(shè),網(wǎng)站改版,服務(wù)器托管租用等互聯(lián)網(wǎng)服務(wù)。
新聞名稱:Linux多線程實(shí)現(xiàn)并行運(yùn)行,提高系統(tǒng)運(yùn)行效率 (linux多線程是并行運(yùn)行)
分享路徑:http://m.fisionsoft.com.cn/article/ccdshgs.html


咨詢
建站咨詢
