版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 摘要</b></p><p> 隨著嵌入式Linux系統(tǒng)的廣泛應(yīng)用和發(fā)展,多線(xiàn)程技術(shù)日益完善。使用多線(xiàn)程編程可以大大增進(jìn)效率。將任務(wù)相關(guān)聯(lián)的各個(gè)線(xiàn)程運(yùn)行在統(tǒng)一地址空間上,并且共享全局變量和內(nèi)存,這樣線(xiàn)程之間共享數(shù)據(jù)很方便,相互間通信也容易,十分利于多線(xiàn)程間的數(shù)據(jù)交互。同時(shí),由于ARM與Linux系統(tǒng)的出色表現(xiàn),基于ARM的Linux嵌入式系統(tǒng)的多線(xiàn)程數(shù)據(jù)交互在
2、實(shí)際應(yīng)用得到很好的推廣,多線(xiàn)程數(shù)據(jù)交互的性能也越來(lái)越受到重視[1][2][10]。研究如何測(cè)試分析多線(xiàn)程間數(shù)據(jù)交互問(wèn)題以及數(shù)據(jù)交互的方式方法十分有意義。這能為多線(xiàn)程的編程提供很好的參考。</p><p> 本文著重研究多線(xiàn)程下數(shù)據(jù)交互的方式方法,并且測(cè)試各種數(shù)據(jù)交互方式的系統(tǒng)性能以及優(yōu)缺點(diǎn)。主要探討了基于互斥鎖的多線(xiàn)程數(shù)據(jù)交互方式、基于條件變量的多線(xiàn)程數(shù)據(jù)交互方式以及基于讀寫(xiě)鎖的多線(xiàn)程數(shù)據(jù)交互方式。通過(guò)設(shè)計(jì)綜合
3、程序,創(chuàng)建六個(gè)線(xiàn)程,分別實(shí)現(xiàn)消費(fèi)者、生產(chǎn)者、讀取、寫(xiě)入數(shù)據(jù)等功能,相互間采用不同的方式方法進(jìn)行數(shù)據(jù)交互,以此來(lái)研究多線(xiàn)程數(shù)據(jù)交互的編程,測(cè)試多線(xiàn)程數(shù)據(jù)交互的性能。整個(gè)設(shè)計(jì)采用C語(yǔ)言,并且調(diào)用線(xiàn)程標(biāo)準(zhǔn)庫(kù)pthread。以此完成整個(gè)設(shè)計(jì)研究。</p><p> 關(guān)鍵詞: Linux; 多線(xiàn)程;ARM;數(shù)據(jù)交互; </p><p><b> Abstract</b>&l
4、t;/p><p> With the extensive application and development of embedded Linux systems, multi-threading technology has improved steadily. Using multi-threaded programming can greatly improve efficiency. If the thr
5、eads in the associated tasks running in the unified address space and shared global variables and memory, the data communication with each other will easily, and it will very conducive to the data exchange between multip
6、le threads. At the same time, as the excellent performance of the ARM and Linux s</p><p> This paper focuses on the ways and means of data exchange in multi-threaded, and test the system performance, as wel
7、l as research the advantages and disadvantages of various data interactively. It will aim at the data interactively based on multi-threaded mutex, condition variable multi-threaded data interactively, and read and write
8、multi-threaded lock . The design process will create six threads, respectively, to achieve the consumer, producer, read, write data and functions among different wa</p><p> Keywords: Linux; multi-threaded;
9、ARM; data exchange;</p><p><b> 1緒論</b></p><p> 隨著嵌入式系統(tǒng)的發(fā)展,多線(xiàn)程編程技術(shù)的應(yīng)用越來(lái)越廣泛。特別是在嵌入式系統(tǒng)中存在大量的數(shù)據(jù)交互,采用多線(xiàn)程技術(shù)就具有得天獨(dú)厚的數(shù)據(jù)交互優(yōu)勢(shì)[3]。因此,總結(jié)多線(xiàn)程中數(shù)據(jù)交互的方式,分析數(shù)據(jù)交互的性能具有重要的意義。</p><p> 1.1研
10、究背景和意義</p><p> 在嵌入式系統(tǒng)高速發(fā)展的同時(shí),各種新型的編程技術(shù)猶如雨后春筍般出現(xiàn)。多線(xiàn)程編程技術(shù)在誕生時(shí)就一直受到較高的關(guān)注,并經(jīng)過(guò)多方的改進(jìn),確定了POSIX多線(xiàn)程標(biāo)準(zhǔn),并不斷發(fā)展完善[9]。</p><p> 在實(shí)際應(yīng)用中,一個(gè)采用了多線(xiàn)程技術(shù)的應(yīng)用程序可以更好地利用系統(tǒng)資源。其主要優(yōu)勢(shì)在于充分利用了CPU的空閑時(shí)間片,可以用盡可能少的時(shí)間來(lái)對(duì)用戶(hù)的要求做出響應(yīng),使
11、得進(jìn)程的整體運(yùn)行效率得到較大提高,同時(shí)增強(qiáng)了應(yīng)用程序的靈活性[4]。更為重要的是,由于同一進(jìn)程的所有線(xiàn)程是共享同一內(nèi)存,所以不需要特殊的數(shù)據(jù)傳送機(jī)制,不需要建立共享存儲(chǔ)區(qū)或共享文件,從而使得不同任務(wù)之間的協(xié)調(diào)操作與運(yùn)行、數(shù)據(jù)的交互、資源的分配等問(wèn)題更加易于解決。多線(xiàn)程數(shù)據(jù)交互采用的是共享內(nèi)存,因而存在互斥與同步操作。POSIX標(biāo)準(zhǔn)提供標(biāo)準(zhǔn)線(xiàn)程庫(kù)pthread。線(xiàn)程庫(kù)中有各種線(xiàn)程同步的方法,這方便了線(xiàn)程間的數(shù)據(jù)交互。</p>
12、<p> 本文在總結(jié)多線(xiàn)程互斥與同步操作的基礎(chǔ)上,設(shè)計(jì)程序測(cè)試多線(xiàn)程數(shù)據(jù)交互的性能。分析在采用多線(xiàn)程進(jìn)行數(shù)據(jù)交互過(guò)程中,各種互斥與同步操作的數(shù)據(jù)交互的效率與資源占用情況。對(duì)比各種多線(xiàn)程數(shù)據(jù)交互的方式方法,能為多線(xiàn)程程序設(shè)計(jì)提供良好的參考。</p><p><b> 1.2論文組織</b></p><p> 本文設(shè)計(jì)中以Linux操作系統(tǒng)作為嵌入式系統(tǒng)
13、的研究對(duì)象,分析多線(xiàn)程程序設(shè)計(jì)中各種線(xiàn)程互斥與同步操作,并設(shè)計(jì)程序,測(cè)試多線(xiàn)程數(shù)據(jù)交互的性能,生成總結(jié)報(bào)告。</p><p> 本文主要由四部分組成:</p><p> 第一部分:介紹論文的研究背景、主要內(nèi)容及組織方式。</p><p> 第二部分:總結(jié)多線(xiàn)程數(shù)據(jù)交互中的各種互斥與同步方式,并分析各種方式的實(shí)現(xiàn)過(guò)程以及存在的優(yōu)缺點(diǎn)。</p>&l
14、t;p> 第三部分:選取在多線(xiàn)程數(shù)據(jù)交互過(guò)程中需要測(cè)試的性能的指標(biāo)以及測(cè)試軟件選擇和基本的操作。</p><p> 第四部分:對(duì)于各種互斥與同步方法設(shè)計(jì)相應(yīng)的測(cè)試程序,觀察測(cè)試結(jié)果,分析產(chǎn)生結(jié)果的原因。在此基礎(chǔ)上設(shè)計(jì)綜合測(cè)試程序,進(jìn)一步分析制約多線(xiàn)程數(shù)據(jù)交互性能的瓶頸。</p><p> 2多線(xiàn)程數(shù)據(jù)交互方法</p><p> 多線(xiàn)程數(shù)據(jù)交互的方法比較
15、成熟,數(shù)量眾多。進(jìn)行多線(xiàn)程編程時(shí),最應(yīng)注意的就是數(shù)據(jù)交互中共享數(shù)據(jù)的問(wèn)題。因?yàn)闊o(wú)法知道哪個(gè)線(xiàn)程會(huì)在哪個(gè)時(shí)候?qū)蚕頂?shù)據(jù)進(jìn)行操作,也無(wú)法知道哪個(gè)線(xiàn)程先運(yùn)行,哪個(gè)線(xiàn)程后運(yùn)行。在一般的多線(xiàn)程數(shù)據(jù)交互中,可以將線(xiàn)程看做進(jìn)程來(lái)進(jìn)行數(shù)據(jù)間的通信[5][7][9]。當(dāng)然,線(xiàn)程有自己獨(dú)有的多線(xiàn)程數(shù)據(jù)交互的方法,主要有互斥鎖方式、條件變量方式、讀寫(xiě)鎖方式、線(xiàn)程信號(hào)方式。</p><p> 2.1使用互斥鎖進(jìn)行數(shù)據(jù)交互</p&
16、gt;<p> 2.1.1 互斥鎖基本原理</p><p> 互斥鎖是最基本也是最簡(jiǎn)單的數(shù)據(jù)交互方式?;コ怄i能夠保證數(shù)據(jù)排他性的訪問(wèn),確保了數(shù)據(jù)的安全性。不過(guò)互斥鎖交互數(shù)據(jù)中,線(xiàn)程之間申請(qǐng)互斥鎖中會(huì)有沖突產(chǎn)生。因而需要在線(xiàn)程解鎖后進(jìn)行延時(shí)。保證其他線(xiàn)程能夠申請(qǐng)到互斥鎖。這降低了線(xiàn)程間通信的效率。影響系統(tǒng)性能[4][7][9][11]。</p><p> 互斥鎖以排他方式
17、防止共享數(shù)據(jù)被并發(fā)修改?;コ怄i是一個(gè)二元變量,其狀態(tài)為開(kāi)鎖和上鎖狀態(tài)。</p><p> 在訪問(wèn)共享資源中,首先申請(qǐng)?jiān)摶コ怄i,如果該互斥鎖處于開(kāi)鎖狀態(tài),則申請(qǐng)到該鎖對(duì)象,并立即占有該資源,以防止其他線(xiàn)程訪問(wèn)該資源;如果該互斥鎖處于鎖定狀態(tài),默認(rèn)阻塞等待。并且,只有鎖定該互斥鎖的進(jìn)程才能釋放該互斥鎖。其他線(xiàn)程的釋放操作無(wú)效。這樣,容易產(chǎn)生死鎖現(xiàn)象,編程時(shí)需要考慮到鎖的各種情況,防止死鎖。</p>&
18、lt;p> 2.1.2互斥鎖數(shù)據(jù)交互方法</p><p> 互斥鎖數(shù)據(jù)交互主要流程包括:使用庫(kù)函數(shù)pthread提供的pthread_mutex_init對(duì)互斥鎖初始化,以此確定互斥鎖的屬性。在讀寫(xiě)數(shù)據(jù)時(shí),使用函數(shù)pthread_mutex_lock對(duì)互斥鎖上鎖,進(jìn)而能對(duì)數(shù)據(jù)進(jìn)行排他性訪問(wèn)。當(dāng)對(duì)數(shù)據(jù)運(yùn)算完成后,需要使用函數(shù)pthread_mutex_unlock進(jìn)行解鎖,使其他的線(xiàn)程可以申請(qǐng)到該鎖。最后
19、,當(dāng)使用完成后,需要函數(shù)pthread_mutex_destroy來(lái)銷(xiāo)毀互斥鎖。有時(shí),為了避免死鎖情況,可以采用函數(shù)pthread_mutex_trylock來(lái)判斷是否上鎖。</p><p> 互斥鎖的操作使用簡(jiǎn)單,能夠?yàn)槎嗑€(xiàn)程間數(shù)據(jù)的交互提供很好的支持。而且,工作過(guò)程穩(wěn)定,不需要另外的設(shè)計(jì)算法。是多線(xiàn)程數(shù)據(jù)交互很好的選擇。</p><p> 2.2使用條件變量進(jìn)行數(shù)據(jù)交互</p
20、><p> 2.2.1 條件變量基本原理</p><p> 條件變量是互斥鎖的補(bǔ)充,互斥鎖能夠解決資源的互斥訪問(wèn),但互斥鎖一個(gè)明顯的缺點(diǎn)是它只有兩種狀態(tài):鎖定和非鎖定。而條件變量通過(guò)允許線(xiàn)程阻塞和等待另一個(gè)線(xiàn)程發(fā)送信號(hào)的方法彌補(bǔ)了互斥鎖的不足,它常和互斥鎖一起使用。條件變量的使用能夠很好的實(shí)現(xiàn)數(shù)據(jù)的交互,在多線(xiàn)程數(shù)據(jù)交互中具有很好的實(shí)用價(jià)值[4][5]。</p><p&
21、gt; 條件變量是互斥鎖的擴(kuò)充,定義一個(gè)條件變量后,需要定義對(duì)應(yīng)的互斥鎖。條件變量被用來(lái)阻塞一個(gè)線(xiàn)程,當(dāng)條件不滿(mǎn)足時(shí),線(xiàn)程往往解開(kāi)相應(yīng)的互斥鎖并等待條件發(fā)生變化。一旦其它的某個(gè)線(xiàn)程改變了條件變量,它將通知相應(yīng)的條件變量喚醒一個(gè)或多個(gè)正被此條件變量阻塞的線(xiàn)程。這些線(xiàn)程將重新鎖定互斥鎖并重新測(cè)試條件是否滿(mǎn)足[15]。</p><p> 2.2.2 條件變量操作過(guò)程</p><p> 使用
22、條件進(jìn)行數(shù)據(jù)交互時(shí),首先,使用函數(shù)pthread_cond_init初始化條件變量,并且要初始化相應(yīng)的互斥鎖。然后鎖定互斥鎖,并調(diào)用函數(shù)pthread_cond_wait阻塞等待條件變量,同時(shí)會(huì)解開(kāi)互斥鎖。當(dāng)其他線(xiàn)程調(diào)用函數(shù)pthread_cond_signal通知等待該條件變量的第一個(gè)線(xiàn)程時(shí),阻塞取消,線(xiàn)程繼續(xù)執(zhí)行。當(dāng)程序運(yùn)行完后,調(diào)用函數(shù)pthread_cond_destroy銷(xiāo)毀條件變量。也可調(diào)用函數(shù)pthread_cond_ti
23、medwait函數(shù)在指定的時(shí)間內(nèi)阻塞等待條件變量。當(dāng)有多個(gè)線(xiàn)程等待變量時(shí),可以調(diào)用函數(shù)pthread_cond_broadcast函數(shù)通知等待該條件變量的所有線(xiàn)程。</p><p> 條件變量的操作相對(duì)互斥鎖是比較復(fù)雜的,但是能夠完成更多的數(shù)據(jù)交互,并且,由于條件變量采用的是通知等待的模式,因而在數(shù)據(jù)交互處理中更加的方便靈活,效率也比互斥鎖要高。是多線(xiàn)程編程中數(shù)據(jù)交互和同步很好的選擇。</p>&
24、lt;p> 2.3使用讀寫(xiě)鎖進(jìn)行數(shù)據(jù)交互</p><p> 2.3.1 讀寫(xiě)鎖基本原理</p><p> 在對(duì)數(shù)據(jù)的讀寫(xiě)應(yīng)用中,更多的操作是讀操作,而寫(xiě)操作較少,例如對(duì)數(shù)據(jù)庫(kù)函數(shù)的讀寫(xiě)應(yīng)用,為了滿(mǎn)足當(dāng)前能夠允許多個(gè)讀寫(xiě),但只允許一個(gè)寫(xiě)入的需求,線(xiàn)程提供了讀寫(xiě)鎖來(lái)實(shí)現(xiàn)。</p><p> 在數(shù)據(jù)交互過(guò)程中,如果有其它線(xiàn)程讀數(shù)據(jù),則允許其他線(xiàn)程執(zhí)行讀操作,
25、但不允許寫(xiě)操作;如果有其它線(xiàn)程寫(xiě)數(shù)據(jù),則其它線(xiàn)程的讀、寫(xiě)操作均允許。</p><p> 在讀寫(xiě)鎖過(guò)程中,如果某線(xiàn)程申請(qǐng)了讀鎖,其他線(xiàn)程可以再申請(qǐng)讀鎖,但不能申請(qǐng)寫(xiě)鎖。如果某線(xiàn)程申請(qǐng)了寫(xiě)鎖,則其它線(xiàn)程不能申請(qǐng)讀鎖,也不能申請(qǐng)寫(xiě)鎖。</p><p> 2.3.2 讀寫(xiě)鎖操作過(guò)程</p><p> 在使用讀寫(xiě)鎖過(guò)程中,首先,調(diào)用函數(shù)pthread_rwlock_in
26、it初始化讀寫(xiě)鎖。當(dāng)需要讀取數(shù)據(jù)時(shí),可以調(diào)用函數(shù)pthread_rwlock_rdlock阻塞申請(qǐng)讀鎖,這個(gè)時(shí)候仍然可以再申請(qǐng)讀鎖,但是不能夠申請(qǐng)寫(xiě)鎖。在需要寫(xiě)數(shù)據(jù)的時(shí)候,可以調(diào)用函數(shù)pthread_rwlock_wrlock阻塞申請(qǐng)寫(xiě)鎖,當(dāng)申請(qǐng)到寫(xiě)鎖后,就不能再申請(qǐng)到讀鎖,也不能申請(qǐng)寫(xiě)鎖。在讀寫(xiě)鎖完成后,可以調(diào)用函數(shù)pthread_rwlock_unlock來(lái)釋放鎖,在不需要讀寫(xiě)鎖后,應(yīng)調(diào)用函數(shù)pthread_rwlock_destr
27、oy來(lái)銷(xiāo)毀讀寫(xiě)鎖。在申請(qǐng)讀寫(xiě)鎖過(guò)程中,可以分別調(diào)用函數(shù)pthread_rwlock_trywrlock和函數(shù)pthread_rwlock_tryrdlock函數(shù)來(lái)進(jìn)行非阻塞申請(qǐng)讀鎖和非阻塞申請(qǐng)寫(xiě)鎖。</p><p> 讀寫(xiě)鎖是基于實(shí)際操作中的讀多于寫(xiě)而設(shè)計(jì)的,在多線(xiàn)程數(shù)據(jù)交互中,能夠避免排他性的讀數(shù)據(jù)而影響整體的性能。同時(shí),讀寫(xiě)鎖也能夠很好的實(shí)現(xiàn)多線(xiàn)程的數(shù)據(jù)交互與同步,具有很好的實(shí)用意義。</p>
28、<p> 2.4其它線(xiàn)程數(shù)據(jù)交互方式</p><p> 2.4.1 信號(hào)量數(shù)據(jù)交互方式</p><p> 信號(hào)量本質(zhì)上是一個(gè)非負(fù)的整數(shù)計(jì)數(shù)器,它被用來(lái)控制對(duì)公共資源的訪問(wèn)。當(dāng)公共資源增加時(shí),調(diào)用函數(shù)sem_post()增加信號(hào)量。只有當(dāng)信號(hào)量值大于0時(shí),才能使用公共資源,使用后,函數(shù)sem_wait()減少信號(hào)量。函數(shù)sem_trywait()和函數(shù)pthread_ mu
29、tex_trylock()起同樣的作用,它是函數(shù)sem_wait()的非阻塞版本。信號(hào)量定義完成了互斥體和條件變量的封裝,按照多線(xiàn)程程序設(shè)計(jì)中訪問(wèn)控制機(jī)制,控制對(duì)資源的同步訪問(wèn),提供程序設(shè)計(jì)人員更方便的調(diào)用接口[12]。</p><p> 2.4.2 線(xiàn)程與信號(hào)數(shù)據(jù)交互方式</p><p> 線(xiàn)程與擁有與信號(hào)相關(guān)的私有數(shù)據(jù)---線(xiàn)程信號(hào)掩碼,這樣,線(xiàn)程可以使用信號(hào)操作來(lái)實(shí)現(xiàn)數(shù)據(jù)的同步,
30、每個(gè)線(xiàn)程可也向別的線(xiàn)程發(fā)送信號(hào),每個(gè)線(xiàn)程可以設(shè)置自己的信號(hào)阻塞集合并設(shè)置針對(duì)某信號(hào)的處理方式,但同一進(jìn)程中對(duì)某信號(hào)的處理方式只能有一個(gè)有效,即最后一次設(shè)置的處理方式。如果別的進(jìn)程向當(dāng)前進(jìn)程中發(fā)送一個(gè)信號(hào),那么由哪個(gè)線(xiàn)程處理則是未知的[6][8][13]。</p><p> 3多線(xiàn)程數(shù)據(jù)性能測(cè)試方法</p><p> 多線(xiàn)程數(shù)據(jù)交互中,監(jiān)測(cè)系統(tǒng)的性能能夠很好的了解多線(xiàn)程數(shù)據(jù)交互中系統(tǒng)存在
31、的瓶頸以及采用數(shù)據(jù)交互方法存在的部分問(wèn)題。在普通的Linux系統(tǒng)監(jiān)測(cè)中,主要包括正在執(zhí)行的進(jìn)程、內(nèi)存的使用率、磁盤(pán)的性能、網(wǎng)絡(luò)流量和CPU的壓力。由于多線(xiàn)程數(shù)據(jù)交互中,系統(tǒng)負(fù)載不會(huì)改變,而又不涉及到網(wǎng)絡(luò)和磁盤(pán)。因此,選擇CPU性能、內(nèi)存使用率以及正在運(yùn)行的進(jìn)程作為監(jiān)測(cè)的指標(biāo)[12][14][15]。</p><p> 3.1 CPU性能測(cè)試</p><p> CPU是電腦的核心硬件,C
32、PU的使用情況對(duì)程序的設(shè)計(jì)有很好的指導(dǎo)作用。在觀察多線(xiàn)程數(shù)據(jù)交互中,使用top命令來(lái)觀察CPU的運(yùn)行。其顯示結(jié)果如圖3.1.1所示。</p><p> 圖3.1.1 top命令運(yùn)行界面</p><p> 在圖中,CPU性能主要觀測(cè)第三行,us表示用戶(hù)空間占用CPU百分比,sy表示內(nèi)核空間占用CPU百分比,ni表示用戶(hù)進(jìn)程空間內(nèi)改變過(guò)優(yōu)先級(jí)的進(jìn)程占用CPU百分比,id表示空閑CPU百分比
33、,wa表示等待輸入輸出的CPU時(shí)間百分比,hi表示硬中斷,si表示軟中斷。</p><p> 在界面第一行中,包含用戶(hù)登錄時(shí)間,當(dāng)前用戶(hù)數(shù)和系統(tǒng)在一分鐘、五分鐘、十五分鐘內(nèi)的平均負(fù)載。第二行中,包含了系統(tǒng)進(jìn)程總數(shù)、正在運(yùn)行、睡眠、僵尸、停止的進(jìn)程數(shù)。而第四行中,包含物理內(nèi)存總量、使用的物理內(nèi)存總量、空閑物理內(nèi)存總量以及用作內(nèi)核緩存的內(nèi)存量。最后是進(jìn)程信息區(qū),包含了進(jìn)程的ID、父進(jìn)程的ID以及CPU的占用率。&l
34、t;/p><p><b> 3.2內(nèi)存性能測(cè)試</b></p><p> 內(nèi)存是Linux內(nèi)核所有管理的重要資源之一,內(nèi)存管理系統(tǒng)是操作系統(tǒng)中的重要部分。在觀察多線(xiàn)程數(shù)據(jù)交互中,采用free命令來(lái)監(jiān)控內(nèi)存使用情況。其界面如圖3.2.1所示。</p><p> 圖3.2.1 free命令界面</p><p> 其中,M
35、em表示物理內(nèi)存統(tǒng)計(jì),包括總共物理內(nèi)存,使用的內(nèi)存,空閑內(nèi)存空間。-/+buffer/cached表示物理內(nèi)存的緩存統(tǒng)計(jì)。Swap表示硬盤(pán)上交換分局的使用情況。在多線(xiàn)程數(shù)據(jù)交互中,主要關(guān)注物理內(nèi)存統(tǒng)計(jì)情況。</p><p> 對(duì)于單獨(dú)程序而言,可以使用命令“pmap –x +進(jìn)程ID”來(lái)獲得進(jìn)程使用內(nèi)存的情況,輸入命令后,其界面圖如下所示:</p><p> 圖3.2.2 命令pmap
36、界面圖</p><p> 由上圖可以得出,程序two_change總共占用內(nèi)存空間為22196KB。并且,可以了解每一個(gè)Mapping對(duì)應(yīng)映像名的起始地址。是觀察單獨(dú)進(jìn)程內(nèi)存使用情況很好的工具。</p><p><b> 3.3進(jìn)程運(yùn)行測(cè)試</b></p><p> 系統(tǒng)進(jìn)程的運(yùn)行對(duì)于分析系統(tǒng)的各項(xiàng)指標(biāo)具有重要的意義,觀察進(jìn)程對(duì)系統(tǒng)資源的
37、占用能更好的理解多線(xiàn)程數(shù)據(jù)交互過(guò)程以及性能。對(duì)于系統(tǒng)進(jìn)程的觀察,采用圖形界面軟件KDE System Guard ,其界面圖如圖3.3.1所示。</p><p> 圖3.3.1 KDE System Guard界面</p><p> 根據(jù)圖形界面顯示,在進(jìn)程表中可以選擇“樹(shù)”形顯示,能夠清楚的了解系統(tǒng)進(jìn)程的關(guān)系。在進(jìn)程列表中,可以查看進(jìn)程的狀態(tài)、進(jìn)程ID以及父進(jìn)程等信息。能夠了解線(xiàn)程占
38、用CPU比例??梢院芎玫姆治鼍€(xiàn)程的運(yùn)行情況。</p><p> 由于圖形界面占用較多的系統(tǒng)資源,在觀察程序運(yùn)行中,可以簡(jiǎn)單的使用“ps –all” 命令,得到如下圖所示界面:</p><p> 圖3.3.2 ps命令界面圖</p><p> 從圖中,可以獲得程序two_change的進(jìn)程ID 為7638.這樣,結(jié)合top命令和pmap命令,能夠很容易的獲得進(jìn)程
39、ID為7638所占用的CPU和內(nèi)存等系統(tǒng)資源。方便對(duì)多線(xiàn)程程序的測(cè)試分析。</p><p> 4測(cè)試步驟及結(jié)果分析</p><p> 通過(guò)分析多線(xiàn)程數(shù)據(jù)交互的各種方法,在總結(jié)成熟技術(shù)基礎(chǔ)上,設(shè)計(jì)程序,分析程序運(yùn)行結(jié)果,測(cè)試多線(xiàn)程數(shù)據(jù)交互中系統(tǒng)的性能。測(cè)試方法采用ps、top、pmap命令,觀察CPU使用率、內(nèi)存使用率以及進(jìn)程運(yùn)行情況。</p><p> 4.1
40、基于互斥鎖的設(shè)計(jì)思路及測(cè)試結(jié)果</p><p> 4.1.1互斥鎖程序設(shè)計(jì)思路</p><p> 利用互斥鎖進(jìn)行數(shù)據(jù)交互是基于互斥鎖在鎖定后,只有鎖定互斥鎖的線(xiàn)程能夠?qū)?shù)據(jù)進(jìn)行訪問(wèn),而其他的線(xiàn)程需要等待線(xiàn)程解鎖后才能進(jìn)行數(shù)據(jù)的訪問(wèn)。這樣,利用互斥鎖就能完成多線(xiàn)程間數(shù)據(jù)交互,避免沖突。</p><p> 設(shè)計(jì)思路上,首先創(chuàng)建兩個(gè)線(xiàn)程,一個(gè)甲線(xiàn)程用于產(chǎn)生隨機(jī)數(shù)據(jù)并
41、寫(xiě)入指定文件和賦值給全局變量,另一個(gè)乙線(xiàn)程用于處理甲線(xiàn)程產(chǎn)生的數(shù)據(jù),具體功能圖和程序流程圖如圖4.1.1、4.1.2所示。</p><p> 圖4.1.1 互斥鎖數(shù)據(jù)交互設(shè)計(jì)圖</p><p> 圖4.1.2 互斥鎖程序設(shè)計(jì)流程圖</p><p> 線(xiàn)程甲、乙是并行執(zhí)行。主線(xiàn)程調(diào)用pthread_join()函數(shù)來(lái)阻塞等待線(xiàn)程甲、乙結(jié)束。線(xiàn)程甲調(diào)用data_p
42、roduce()函數(shù)來(lái)產(chǎn)生隨機(jī)數(shù)據(jù),并且將產(chǎn)生的隨機(jī)數(shù)據(jù)傳遞給全局變量temp。線(xiàn)程乙調(diào)用data_handle()處理數(shù)據(jù),對(duì)全局變量temp的數(shù)據(jù)進(jìn)行數(shù)學(xué)運(yùn)算。整個(gè)數(shù)據(jù)交互過(guò)程采用全局變量的方式來(lái)傳遞數(shù)據(jù)。部分源程序如下所示。</p><p> 線(xiàn)程甲產(chǎn)生隨機(jī)數(shù)據(jù),并賦值給全局變量,其函數(shù)data_produce()源程序如下:</p><p> void* data_produc
43、e(void*arg)</p><p><b> {</b></p><p><b> int i=0;</b></p><p><b> while(1){</b></p><p> pthread_mutex_lock(&data_mutex);</p
44、><p> temp=rand();</p><p><b> i++;</b></p><p> printf(“%d\n”,i);</p><p> pthread_mutex_unlock(&data_mutex);</p><p><b> sleep(1);<
45、;/b></p><p><b> }</b></p><p><b> }</b></p><p> 數(shù)據(jù)產(chǎn)生函數(shù)是一個(gè)死循環(huán)過(guò)程,不停的使用鎖定互斥量data_mutex來(lái)對(duì)全局變量temp進(jìn)行排他性訪問(wèn)。在賦值完成后,再解鎖,并且等待1s中,以便其他線(xiàn)程獲取互斥量而對(duì)數(shù)據(jù)進(jìn)行讀取。</p>
46、<p> 線(xiàn)程乙讀取全局變量數(shù)據(jù),并且進(jìn)行簡(jiǎn)單處理,其函數(shù)data_handle()源程序如下:</p><p> void* data_handle(void*arg)</p><p><b> {</b></p><p> int num,i;</p><p><b> double j
47、;</b></p><p><b> num =0;</b></p><p><b> while(1){</b></p><p> pthread_mutex_lock(&data_mutex);</p><p><b> j=temp;</b>&
48、lt;/p><p><b> num++;</b></p><p> printf("%d\n",num);</p><p> pthread_mutex_unlock(&data_mutex);</p><p> sleep(1); </p><p><b&
49、gt; }</b></p><p><b> }</b></p><p> 在data_handle()函數(shù)中,執(zhí)行的是死循環(huán),不停的讀取數(shù)據(jù)并將全局變量的數(shù)據(jù)進(jìn)行運(yùn)算賦值。而為確保數(shù)據(jù)交互的可靠性,在讀取數(shù)據(jù)前執(zhí)行鎖定互斥量data_mutex的操作。當(dāng)甲線(xiàn)程鎖定互斥量后,乙線(xiàn)程將阻塞等待,同樣,甲線(xiàn)程在乙線(xiàn)程鎖定互斥量后也會(huì)阻塞等待。乙在讀取處理
50、完數(shù)據(jù)后會(huì)解鎖,此時(shí),等待上鎖的甲線(xiàn)程會(huì)立即獲得互斥鎖。這樣就保證了數(shù)據(jù)能夠正確的讀取和處理。</p><p> 4.1.2互斥鎖數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 通過(guò)分析程序,在線(xiàn)程乙中,插入變量num,每次處理完數(shù)據(jù)后都進(jìn)行加一操作,并顯示num變量值。同樣,在線(xiàn)程甲中定義變量i,進(jìn)行同樣的操作,程序運(yùn)行結(jié)果如下:</p><p> 圖4.1.3 互斥鎖
51、程序運(yùn)行結(jié)果</p><p> 根據(jù)上圖結(jié)果表明,總會(huì)有兩個(gè)同樣的數(shù)據(jù)顯示,一個(gè)是甲線(xiàn)程中的變量i,一個(gè)是乙線(xiàn)程中的變量num,兩個(gè)線(xiàn)程在各自線(xiàn)程每運(yùn)行一次都會(huì)加一并且打印結(jié)果。因此可知,線(xiàn)程甲、乙交替運(yùn)行,全局變量temp在甲線(xiàn)程賦值后很快被乙線(xiàn)程讀取數(shù)據(jù),在讀取數(shù)據(jù)后,甲線(xiàn)程才再次給temp賦值,整個(gè)實(shí)現(xiàn)過(guò)程沒(méi)有沖突出現(xiàn)?;コ怄i進(jìn)行數(shù)據(jù)交互中,能夠很好的完成數(shù)據(jù)的交互。</p><p&g
52、t; 采用top命令,觀察進(jìn)程PID為7197的運(yùn)行狀態(tài),即調(diào)試程序的運(yùn)行??芍?,CPU占用率為3.0%,內(nèi)存使用了502M。</p><p> 圖4.1.4 互斥鎖測(cè)試程序結(jié)果</p><p> 根據(jù)上述top命令結(jié)果分析,由于互斥鎖操作中,需要等待操作,而等待操作過(guò)程中,CPU空閑,因此,CPU的使用率十分的低,調(diào)用pmap命令查看程序運(yùn)行單獨(dú)內(nèi)存,內(nèi)存占用大小為22200KB,
53、說(shuō)明使用互斥鎖進(jìn)行數(shù)據(jù)交互過(guò)程中,對(duì)系統(tǒng)資源占用十分的少,主要占用的是內(nèi)存資源。當(dāng)去掉等待時(shí)間時(shí)。部分源程序如下。</p><p> 甲線(xiàn)程修改后函數(shù)data_produce()源程序如下:</p><p> void* data_produce(void*arg)</p><p><b> {</b></p><p&
54、gt;<b> int i=0;</b></p><p><b> while(1){</b></p><p> for(i=0;i<10000;i++){</p><p> pthread_mutex_lock(&data_mutex);</p><p> sum_temp
55、--;</p><p> pthread_mutex_unlock(&data_mutex);</p><p><b> }</b></p><p><b> temp++;</b></p><p> printf("produce data is %d\n",t
56、emp);</p><p><b> }</b></p><p><b> }</b></p><p> 在修改中,去掉了等待時(shí)間,并且在互斥操作中對(duì)互斥鎖data_mutex進(jìn)行一萬(wàn)次的重復(fù)操作,并且在解鎖操作后不去等待而直接的進(jìn)行上鎖操作。</p><p> 線(xiàn)程乙數(shù)據(jù)處理函數(shù)data_
57、handle()源程序修改后如下:</p><p> void* data_handle(void*arg)</p><p><b> {</b></p><p> int num,i;</p><p><b> double j;</b></p><p><b
58、> num =0;</b></p><p><b> while(1){</b></p><p> for(i=0;i<10000;i++){</p><p> pthread_mutex_lock(&data_mutex);</p><p> sum_temp++;</p
59、><p> pthread_mutex_unlock(&data_mutex);</p><p><b> }</b></p><p><b> temp++;</b></p><p> printf("handle data is %d\n",temp);</
60、p><p><b> }</b></p><p><b> }</b></p><p> 線(xiàn)程乙處理數(shù)據(jù)也沒(méi)有加入等待操作,直接對(duì)互斥量進(jìn)行上鎖和解鎖操作,這樣,在上鎖過(guò)程中,甲線(xiàn)程和乙線(xiàn)程上鎖就是隨機(jī)競(jìng)爭(zhēng)的。這不能保證當(dāng)甲線(xiàn)程產(chǎn)生數(shù)據(jù)后,乙線(xiàn)程能夠立即的對(duì)數(shù)據(jù)進(jìn)行處理,相反,甲線(xiàn)程幾乎會(huì)一直占有互斥鎖,而乙線(xiàn)程會(huì)一直的
61、阻塞等待。 </p><p> 運(yùn)行改編后的程序,結(jié)果如下:</p><p> 圖4.1.5 無(wú)等待時(shí)間運(yùn)行結(jié)果</p><p> 根據(jù)結(jié)果顯示,線(xiàn)程甲和線(xiàn)程乙在任意一個(gè)占用互斥鎖后,會(huì)一直的占用,并且不停的運(yùn)行,直到下次另一個(gè)線(xiàn)程搶占到互斥鎖。這樣,線(xiàn)程間的數(shù)據(jù)交互就會(huì)出現(xiàn)不同步的問(wèn)題。這對(duì)數(shù)據(jù)交互來(lái)說(shuō),是十分危險(xiǎn)的。因此,在使用互斥鎖過(guò)程中,插入等待
62、時(shí)間是有必要的。</p><p> 通過(guò)調(diào)用top命令,可觀察得到新的檢測(cè)圖如圖4.1.6所示。</p><p> 圖4.1.6 無(wú)等待時(shí)間系統(tǒng)狀態(tài)</p><p> 由top命令的監(jiān)測(cè)結(jié)果可知,系統(tǒng)運(yùn)行的在滿(mǎn)負(fù)荷狀態(tài),CPU占用率達(dá)到95.0%,內(nèi)存也使用在滿(mǎn)負(fù)荷狀態(tài),但是,由于沒(méi)有系統(tǒng)等待,很多互斥鎖的申請(qǐng)一直由某一個(gè)線(xiàn)程占有,而其它線(xiàn)程阻塞等待。整個(gè)申請(qǐng)
63、搶占互斥鎖是隨機(jī)的過(guò)程,存在很大的數(shù)據(jù)交換問(wèn)題。內(nèi)存占用大小為22196KB。相對(duì)于含有等待時(shí)間的互斥鎖數(shù)據(jù)交互而言,內(nèi)存變化不大,這說(shuō)明對(duì)于基于互斥鎖的多線(xiàn)程數(shù)據(jù)交互過(guò)程,CPU的負(fù)載主要是用于線(xiàn)程內(nèi)部的數(shù)據(jù)處理,而線(xiàn)程間的切換和同步,并不占用過(guò)多的CPU資源。</p><p> 4.2基于條件變量的設(shè)計(jì)思路及測(cè)試結(jié)果</p><p> 4.2.1 條件變量程序設(shè)計(jì)思路</p&
64、gt;<p> 基于條件變量的程序設(shè)計(jì)是創(chuàng)建兩個(gè)線(xiàn)程,一個(gè)生產(chǎn)者線(xiàn)程,一個(gè)消費(fèi)者線(xiàn)程。并且定義一個(gè)具有兩個(gè)緩存區(qū)的結(jié)構(gòu)體,生產(chǎn)者線(xiàn)程寫(xiě)入數(shù)據(jù),消費(fèi)者線(xiàn)程讀取數(shù)據(jù)。通過(guò)條件變量和互斥鎖結(jié)合使用,實(shí)現(xiàn)數(shù)據(jù)的交互。具體工作過(guò)程如圖4.2.1所示。</p><p> 圖4.2.1 條件變量數(shù)據(jù)交互設(shè)計(jì)圖</p><p> 由圖可知,與基于互斥鎖的數(shù)據(jù)交互相比,基于條件變量的數(shù)據(jù)
65、交互設(shè)計(jì)添加了等待非空、非滿(mǎn)信號(hào)。利用這種機(jī)制,可以很好的實(shí)現(xiàn)數(shù)據(jù)交互中的問(wèn)題。在具體實(shí)現(xiàn)過(guò)程中,定義一個(gè)結(jié)構(gòu)體buffer作為臨時(shí)的緩存區(qū),用put函數(shù)向緩存區(qū)寫(xiě)入數(shù)據(jù),當(dāng)寫(xiě)入數(shù)據(jù)完成后,將發(fā)送非空條件變量,當(dāng)寫(xiě)滿(mǎn)后阻塞等待非滿(mǎn)條件變量;用get函數(shù)讀取臨時(shí)變量,當(dāng)讀取一個(gè)數(shù)據(jù)后,將發(fā)送非滿(mǎn)條件變量,當(dāng)讀取完所有數(shù)據(jù)后阻塞等待非空條件變量。而消費(fèi)者線(xiàn)程循環(huán)調(diào)用get函數(shù),生產(chǎn)者線(xiàn)程循環(huán)調(diào)用put函數(shù)。部分源程序如下。</p>
66、;<p> 臨時(shí)緩存區(qū)結(jié)構(gòu)體buffer定義如下:</p><p> struct prodcons{</p><p> int buffer[BUFFER_SIZE];//生產(chǎn)產(chǎn)品值</p><p> pthread_mutex_t lock;//互斥鎖</p><p> int readpos,writepos;/
67、/讀寫(xiě)位置</p><p> pthread_cond_t notempty;//非空條件變量</p><p> pthread_cond_t notfull;//非滿(mǎn)條件變量</p><p><b> } ; </b></p><p> struct prodcons buffer;</p>&l
68、t;p> 在buffer結(jié)構(gòu)體中,定義了一個(gè)兩位數(shù)的一維數(shù)組buffer[]作為數(shù)據(jù)緩存區(qū);并且定義了互斥鎖和兩個(gè)條件變量分別表示非空和非滿(mǎn);為了便于判斷,定義了讀位置和寫(xiě)位置兩個(gè)變量,表示讀寫(xiě)數(shù)組的位置。</p><p> 生產(chǎn)者調(diào)用put函數(shù)源程序如下:</p><p> void put(struct prodcons *prod,int data)//輸入產(chǎn)品子函數(shù)&l
69、t;/p><p><b> {</b></p><p> pthread_mutex_lock(&prod->lock);</p><p> while((prod->writepos+1)%BUFFER_SIZE ==prod->readpos){</p><p> printf(&quo
70、t;producer wait for not full \n");</p><p> pthread_cond_wait(&prod->notfull,&prod->lock);</p><p><b> }</b></p><p> prod->buffer[prod->writepo
71、s]=data;</p><p> prod->writepos++;</p><p> if(prod->writepos >= BUFFER_SIZE)</p><p> prod->writepos =0;</p><p> pthread_cond_signal(&prod->notemp
72、ty);</p><p> pthread_mutex_unlock(&prod->lock);</p><p><b> }</b></p><p> 在生產(chǎn)者調(diào)用put函數(shù)后,將隨機(jī)數(shù)據(jù)傳遞給data,并且將定義的緩存區(qū)buffer傳遞給put函數(shù)。進(jìn)入put函數(shù)后,首先判斷buffer是否已滿(mǎn),當(dāng)buffer已滿(mǎn)后會(huì)阻
73、塞等待,直到消費(fèi)者線(xiàn)程發(fā)送未滿(mǎn)條件變量。收到信號(hào)后,會(huì)向buffer寫(xiě)入數(shù)據(jù),并且發(fā)送非空條件變量,激活等待非空條件變量的線(xiàn)程。并且改變寫(xiě)位置變量值。</p><p> 消費(fèi)者調(diào)用get函數(shù)源程序如下:</p><p> int get(struct prodcons *prod)</p><p><b> {</b></p>
74、<p><b> int data;</b></p><p> pthread_mutex_lock(&prod->lock);</p><p> while(prod->writepos == prod->readpos){</p><p> printf("consumer wait
75、 for not empty \n");</p><p> pthread_cond_wait(&prod->notempty,&prod->lock);</p><p><b> }</b></p><p> data = prod->buffer[prod->readpos];<
76、/p><p> prod->readpos++;</p><p> if(prod->readpos >= BUFFER_SIZE){</p><p> prod->readpos =0;</p><p><b> }</b></p><p> pthread_con
77、d_signal(&prod->notfull);</p><p> pthread_mutex_unlock(&prod->lock);</p><p> return data;</p><p><b> }</b></p><p> 在消費(fèi)者調(diào)用get函數(shù)后,與put函數(shù)相似。會(huì)
78、判斷非空并且會(huì)阻塞等待非空信號(hào)。當(dāng)讀取數(shù)據(jù)后,將數(shù)據(jù)返回給消費(fèi)者,并且發(fā)送非滿(mǎn)條件變量。激活等待非滿(mǎn)條件變量的線(xiàn)程。一般情況下,消費(fèi)者與生產(chǎn)者都會(huì)出現(xiàn)阻塞等待情況。</p><p> 4.2.2 條件變量數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 運(yùn)行程序,其結(jié)果如下:</p><p> 圖4.2.2 條件變量程序運(yùn)行結(jié)果</p><p>
79、由結(jié)果分析可知,生產(chǎn)者線(xiàn)程放入一個(gè)數(shù)據(jù)后,消費(fèi)者線(xiàn)程讀取一個(gè)數(shù)據(jù);之后生產(chǎn)者連續(xù)放入兩個(gè)數(shù)據(jù),然后阻塞等待非滿(mǎn)條件變量。當(dāng)消費(fèi)者線(xiàn)程讀取一個(gè)數(shù)據(jù)后,生產(chǎn)者線(xiàn)程接著放入數(shù)據(jù),如此循環(huán),能夠保證生產(chǎn)者消費(fèi)者數(shù)據(jù)交互高效進(jìn)行。</p><p> 通過(guò)調(diào)用top命令,觀察程序運(yùn)行情況如圖4.2.3所示。</p><p> 圖4.2.3 條件變量數(shù)據(jù)交互測(cè)試結(jié)果</p><p
80、> 程序運(yùn)行時(shí)CPU占用率占用率很低,內(nèi)存占用大小為22204KB。這說(shuō)明基于條件變量的多線(xiàn)程數(shù)據(jù)交互對(duì)系統(tǒng)要求很低。主要是對(duì)內(nèi)存資源占用大。</p><p> 4.3基于讀寫(xiě)鎖與線(xiàn)程信號(hào)的設(shè)計(jì)思路及測(cè)試結(jié)果</p><p> 4.3.1 讀寫(xiě)鎖程序設(shè)計(jì)思路</p><p> 基于讀寫(xiě)鎖程序設(shè)計(jì)是創(chuàng)建四個(gè)線(xiàn)程,兩個(gè)讀線(xiàn)程,兩個(gè)寫(xiě)線(xiàn)程。兩個(gè)寫(xiě)線(xiàn)程向數(shù)組中
81、寫(xiě)入數(shù)據(jù),并且分別申請(qǐng)寫(xiě)鎖,防止寫(xiě)入數(shù)據(jù)沖突;兩個(gè)讀線(xiàn)程同時(shí)讀取寫(xiě)入的數(shù)據(jù),并且競(jìng)爭(zhēng)。當(dāng)寫(xiě)線(xiàn)程申請(qǐng)到寫(xiě)鎖后讀線(xiàn)程將被阻塞,同時(shí)另一個(gè)寫(xiě)線(xiàn)程也被阻塞。而申請(qǐng)到讀線(xiàn)程后,另一個(gè)讀線(xiàn)程也可以申請(qǐng)讀鎖,但是寫(xiě)線(xiàn)程被阻塞。具體功能圖如圖4.3.1所示。</p><p> 圖4.3.1 基于讀寫(xiě)鎖的程序設(shè)計(jì)</p><p> 程序?qū)崿F(xiàn)方式與互斥鎖實(shí)現(xiàn)方式相似,通過(guò)調(diào)用thread_function
82、_read_o()函數(shù)來(lái)讀數(shù)據(jù),通過(guò)調(diào)用thread_function_write_o()函數(shù)來(lái)向緩存數(shù)組寫(xiě)入數(shù)據(jù)。讀寫(xiě)操作均需要調(diào)用讀寫(xiě)鎖來(lái)保證共享數(shù)據(jù)能夠?qū)崿F(xiàn)安全訪問(wèn)。部分源代碼如下所示。</p><p> 寫(xiě)線(xiàn)程甲函數(shù)thread_function_write_o源程序如下:</p><p> void *thread_function_write_o(void *arg)<
83、;/p><p><b> {</b></p><p> printf(" write thread one try to get lock \n");</p><p> for(;i<WORK_SIZE;i++){</p><p> pthread_rwlock_wrlock(&rw
84、lock);</p><p> printf("this is write one thread ,write the %d position \n",i);</p><p> work_area[i]=rand();</p><p> pthread_rwlock_unlock(&rwlock);</p><p
85、><b> sleep(3);</b></p><p><b> }</b></p><p> pthread_exit(0);</p><p><b> }</b></p><p> 進(jìn)入寫(xiě)線(xiàn)程后,首先鎖定讀寫(xiě)鎖,防止其它讀線(xiàn)程或者寫(xiě)線(xiàn)程修改數(shù)據(jù),然后向緩存數(shù)
86、組寫(xiě)入數(shù)據(jù),在寫(xiě)操作完成后,解開(kāi)讀寫(xiě)鎖,并且進(jìn)入休眠,將讀寫(xiě)鎖交給其它線(xiàn)程。在休眠3秒鐘后再次搶占讀寫(xiě)鎖。</p><p> 讀線(xiàn)程甲的函數(shù)thread_function_write_o源程序如下:</p><p> void *thread_function_read_o(void *arg)</p><p><b> {</b><
87、;/p><p> printf("thread read one try to get lock ,");</p><p> while(i<WORK_SIZE){</p><p> pthread_rwlock_rdlock(&rwlock);</p><p> printf("this is
88、 thread read one\n ");</p><p> printf("the %d position value is %d\n",i,work_area[i]);</p><p> pthread_rwlock_unlock(&rwlock);</p><p><b> sleep(2);</b
89、></p><p><b> }</b></p><p> pthread_exit(0);</p><p><b> } </b></p><p> 讀線(xiàn)程與寫(xiě)線(xiàn)程操作相似,讀線(xiàn)程可以有多個(gè)同時(shí)申請(qǐng)讀鎖,但是申請(qǐng)到讀鎖后,寫(xiě)鎖就被阻塞。</p><p> 4
90、.3.2 讀寫(xiě)鎖數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 運(yùn)行程序,結(jié)果如下所示:</p><p> 圖4.3.2 讀寫(xiě)鎖程序運(yùn)行結(jié)果</p><p> 由結(jié)果可知,寫(xiě)線(xiàn)程甲在申請(qǐng)到寫(xiě)鎖后,向數(shù)組位置0、1寫(xiě)入數(shù)據(jù),而寫(xiě)線(xiàn)程乙在之后申請(qǐng)到寫(xiě)鎖,并向位置2寫(xiě)入數(shù)據(jù)。讀鎖是同時(shí)進(jìn)行的,當(dāng)寫(xiě)鎖解鎖后,讀線(xiàn)程甲、乙都可以申請(qǐng)讀線(xiàn)程,并且顯示出寫(xiě)入的數(shù)據(jù)。不存在讀線(xiàn)程相互阻塞
91、。但是當(dāng)有寫(xiě)線(xiàn)程申請(qǐng)到寫(xiě)鎖時(shí),讀線(xiàn)程阻塞,同樣,在有讀線(xiàn)程申請(qǐng)到讀鎖時(shí),寫(xiě)線(xiàn)程也會(huì)阻塞。這樣,寫(xiě)入數(shù)組的數(shù)據(jù)能夠保證順序無(wú)重復(fù)的寫(xiě)入,而且能夠被多次讀取。</p><p> 運(yùn)行程序,調(diào)用top命令,得到線(xiàn)程運(yùn)行狀態(tài)如圖4.3.3所示。</p><p> 圖4.3.3 讀寫(xiě)鎖數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 同樣,基于共享變量的機(jī)制,讀寫(xiě)鎖占用系統(tǒng)資源也十分
92、的少,程序運(yùn)行過(guò)程中CPU、內(nèi)存占用率都十分的低。通過(guò)調(diào)用pmap命令,可得程序內(nèi)存占用大小為42688KB。這相對(duì)于互斥鎖與條件變量來(lái)說(shuō),是兩倍的差距,而這次創(chuàng)建了四個(gè)線(xiàn)程,之前的程序只是創(chuàng)建了兩個(gè)線(xiàn)程,但是CPU的使用率依舊非常的低,這說(shuō)明,在多線(xiàn)程數(shù)據(jù)交互中,CPU的使用率只是與線(xiàn)程中數(shù)據(jù)運(yùn)算的多少有關(guān),而與線(xiàn)程的多少和數(shù)據(jù)交互多少無(wú)關(guān)。但是,內(nèi)存的多少卻是隨著線(xiàn)程的增加而增加。</p><p> 4.4
93、整體數(shù)據(jù)交互方法設(shè)計(jì)思路與測(cè)試結(jié)果</p><p> 4.4.1整體數(shù)據(jù)交互程序設(shè)計(jì)思路</p><p> 在前期設(shè)計(jì)的基礎(chǔ)上,設(shè)計(jì)中采用互斥鎖、條件變量及讀寫(xiě)鎖綜合設(shè)計(jì)程序。程序設(shè)計(jì)了六個(gè)線(xiàn)程。由生產(chǎn)者線(xiàn)程向緩沖區(qū)寫(xiě)入數(shù)據(jù),消費(fèi)者線(xiàn)程讀取數(shù)據(jù),并且由兩個(gè)寫(xiě)線(xiàn)程同時(shí)向數(shù)組中寫(xiě)入數(shù)據(jù)。同時(shí)兩個(gè)讀線(xiàn)程一起讀取寫(xiě)入的數(shù)據(jù)。整體流程圖如圖4.1.1所示。</p><p>
94、; 圖4.4.1 整體設(shè)計(jì)圖</p><p> 程序設(shè)計(jì)十分的復(fù)雜,數(shù)據(jù)間交互采用了互斥鎖,條件變量以及讀寫(xiě)鎖方式。生產(chǎn)者消費(fèi)者線(xiàn)程間采用條件變量進(jìn)行數(shù)據(jù)交互,消費(fèi)者與寫(xiě)線(xiàn)程間采用互斥鎖進(jìn)行通信,而讀寫(xiě)線(xiàn)程間采用讀寫(xiě)鎖進(jìn)行通信。從而保證程序數(shù)據(jù)交互的安全性。部分源程序如下:</p><p> 消費(fèi)者線(xiàn)程函數(shù)get源程序:int get(struct prodcons *prod)&
95、lt;/p><p><b> {</b></p><p><b> int data;</b></p><p> pthread_mutex_lock(&prod->lock);</p><p> while(prod->writepos == prod->readpo
96、s){</p><p> printf("consumer wait for not empty \n");</p><p> pthread_cond_wait(&prod->notempty,&prod->lock);</p><p><b> }</b></p><
97、p> data = prod->buffer[prod->readpos];</p><p> pthread_mutex_lock(&data_mutex);</p><p> temp =data;</p><p> pthread_mutex_unlock(&data_mutex);</p><p&
98、gt; prod->readpos++;</p><p> if(prod->readpos >= BUFFER_SIZE){</p><p> prod->readpos =0;</p><p><b> }</b></p><p> pthread_cond_signal(&
99、prod->notfull);</p><p> pthread_mutex_unlock(&prod->lock);</p><p> return data;</p><p><b> }</b></p><p> 消費(fèi)者線(xiàn)程中,添加了互斥量data_mutex,使用互斥鎖,將產(chǎn)生的數(shù)據(jù)傳
100、遞全局變量temp,互斥鎖能夠很好的保證在向temp寫(xiě)數(shù)據(jù)與讀數(shù)據(jù)時(shí)不產(chǎn)生沖突。生產(chǎn)者線(xiàn)程與消費(fèi)者線(xiàn)程間數(shù)據(jù)同步采用條件變量方式,可以很好的實(shí)現(xiàn)生產(chǎn)消費(fèi),并且輸出數(shù)據(jù)給其它線(xiàn)程使用數(shù)據(jù)。</p><p> 寫(xiě)線(xiàn)程甲的函數(shù)thread_function_write_o源程序如下:</p><p> void *thread_function_write_o(void *arg)</
101、p><p><b> {</b></p><p> printf(" write thread one try to get lock \n");</p><p> for(;i<WORK_SIZE;i++){</p><p> pthread_rwlock_wrlock(&rwlo
102、ck);</p><p> printf("this is write one thread ,write the %d position \n",i);</p><p> pthread_mutex_lock(&data_mutex);</p><p> work_area[i]=temp;</p><p>
103、; pthread_mutex_unlock(&data_mutex);</p><p> pthread_rwlock_unlock(&rwlock);</p><p><b> sleep(3);</b></p><p><b> }</b></p><p> pthr
104、ead_exit(0);</p><p><b> }</b></p><p> 寫(xiě)線(xiàn)程接收數(shù)據(jù),并且將數(shù)據(jù)寫(xiě)入緩存數(shù)組中。數(shù)據(jù)來(lái)自全局變量temp,并且使用互斥鎖,來(lái)完成讀寫(xiě)temp數(shù)據(jù)的安全性。而寫(xiě)線(xiàn)程與其他讀寫(xiě)線(xiàn)程間采用讀寫(xiě)鎖進(jìn)行同步。在寫(xiě)線(xiàn)程中,還有寫(xiě)線(xiàn)程乙,與寫(xiě)線(xiàn)程甲具有相同的作用。寫(xiě)線(xiàn)程甲乙相互競(jìng)爭(zhēng),向緩存數(shù)據(jù)順序?qū)懭霐?shù)據(jù)。讀線(xiàn)程可以同步讀取寫(xiě)入數(shù)組的
105、數(shù)據(jù)。</p><p> 4.4.2 整體數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 運(yùn)行程序,結(jié)果如下所示:</p><p> 圖4.4.2 整體程序運(yùn)行結(jié)果</p><p> 根據(jù)結(jié)果顯示,所有線(xiàn)程同步運(yùn)行,但是消費(fèi)者線(xiàn)程首先被非空條件變量阻塞,讀寫(xiě)線(xiàn)程比生產(chǎn)者線(xiàn)程提前運(yùn)行,造成寫(xiě)入數(shù)據(jù)0號(hào)位置的值為0。當(dāng)生產(chǎn)者線(xiàn)程執(zhí)行后,消費(fèi)者線(xiàn)程讀取
106、第一個(gè)數(shù)據(jù)。寫(xiě)線(xiàn)程將數(shù)據(jù)寫(xiě)入數(shù)組,讀線(xiàn)程讀取顯示數(shù)據(jù)。多線(xiàn)程之間數(shù)據(jù)交按照生產(chǎn)、消費(fèi)、寫(xiě)入、讀取順序進(jìn)行,數(shù)據(jù)交互十分良好,沒(méi)有出現(xiàn)沖突現(xiàn)象。</p><p> 調(diào)用top命令,程序運(yùn)行狀態(tài)如圖4.4.3所示。</p><p> 圖4.4.3 整體數(shù)據(jù)交互測(cè)試結(jié)果</p><p> 根據(jù)結(jié)果顯示,雖然含有七個(gè)線(xiàn)程,并且數(shù)據(jù)交互頻繁,但是程序占用系統(tǒng)資源依然十分
107、的少。CPU占用率和內(nèi)存使用率也很低。程序運(yùn)行很好。使用pmap命令查看內(nèi)存具體使用情況時(shí),內(nèi)存使用大小為63180KB,占用系統(tǒng)資源十分的少。根據(jù)前面的測(cè)試,互斥鎖數(shù)據(jù)交互占用內(nèi)存22196KB、條件變量數(shù)據(jù)交互內(nèi)存占用22204KB、讀寫(xiě)鎖數(shù)據(jù)交互42688KB。系統(tǒng)內(nèi)存占用情況要少于全部?jī)?nèi)存的簡(jiǎn)單疊加。但是內(nèi)存占用是比較大得。</p><p> 根據(jù)以上分析,多線(xiàn)程數(shù)據(jù)交互過(guò)程中,所占用的CPU資源十分的
108、少,然而內(nèi)存空間占用相對(duì)較多。多線(xiàn)程數(shù)據(jù)交互中,要保證數(shù)據(jù)訪問(wèn)能安全進(jìn)行,就需要線(xiàn)程同步,而線(xiàn)程同步過(guò)程中,會(huì)消耗大量的時(shí)間,以至于對(duì)CPU資源的使用較少,同時(shí),線(xiàn)程間的數(shù)據(jù)傳遞是采用共享內(nèi)存的方式進(jìn)行,對(duì)CPU需求較少。然而,對(duì)于內(nèi)存資源,線(xiàn)程間數(shù)據(jù)傳遞會(huì)占用較多的內(nèi)存,這樣,在單純的進(jìn)行多線(xiàn)程數(shù)據(jù)交互時(shí),對(duì)內(nèi)存的要求遠(yuǎn)高于對(duì)CPU的要求。</p><p><b> 5總結(jié)與展望</b>
109、</p><p> Linux的多線(xiàn)程技術(shù)是一項(xiàng)十分前沿的編程技術(shù),而多線(xiàn)程交互數(shù)據(jù)的技術(shù)仍然在探索中,基于ARM的多線(xiàn)程數(shù)據(jù)交互的性能是在分析多線(xiàn)程數(shù)據(jù)交互的基礎(chǔ)上,測(cè)試多線(xiàn)程數(shù)據(jù)交互中,系統(tǒng)的的資源占用情況。</p><p> 在本文的設(shè)計(jì)中,通過(guò)測(cè)試分析,多線(xiàn)程數(shù)據(jù)交互的方式主要有互斥鎖方式、條件變量方式、讀寫(xiě)鎖方式。每一種多線(xiàn)程數(shù)據(jù)交互的方式CPU占用率十分的少,在設(shè)計(jì)對(duì)比過(guò)程
110、中,由于要盡量保證單一變量的方式,因此,不能夠在多線(xiàn)程中進(jìn)行頻繁的占用CPU操作。而單一的多線(xiàn)程數(shù)據(jù)交互中,線(xiàn)程間數(shù)據(jù)交互由于要采用同步機(jī)制,則線(xiàn)程間都需要等待同步,這樣的后果是CPU的使用率明顯的降低。這個(gè)問(wèn)題需要進(jìn)一步的探索。</p><p> 多線(xiàn)程技術(shù)在嵌入式實(shí)時(shí)系統(tǒng)中具有明顯的優(yōu)勢(shì)。線(xiàn)程能夠同步的執(zhí)行,這樣能極大的提高程序的并行性,充分利用多核處理器的資源。由于線(xiàn)程共享進(jìn)程地址空間內(nèi)的所有資源,所以線(xiàn)
111、程之間的通信是很方便的。多個(gè)線(xiàn)程處理不同的任務(wù),增加了程序的并發(fā)性,是程序更高效的執(zhí)行。這些優(yōu)勢(shì)都是多線(xiàn)程技術(shù)得到了很大得重視,而多線(xiàn)程的數(shù)據(jù)交換性能在很大程度上影響系統(tǒng)整體的性能。分析多線(xiàn)程數(shù)據(jù)交換的性能,能在一定程度上解決系統(tǒng)的瓶頸問(wèn)題,使系統(tǒng)能夠更加高效的運(yùn)行。</p><p> 多線(xiàn)程的數(shù)據(jù)交互技術(shù)仍然需要改進(jìn),在利用線(xiàn)程同步機(jī)制過(guò)程中,線(xiàn)程的等待時(shí)間過(guò)長(zhǎng),這不利于系統(tǒng)的實(shí)時(shí)性。雖然可以降低等待同步時(shí)間
112、,但是容易產(chǎn)生讀寫(xiě)數(shù)據(jù)沖突或者數(shù)據(jù)不能有序的讀寫(xiě)。同時(shí),在使用互斥鎖過(guò)程中,當(dāng)出現(xiàn)死鎖問(wèn)題時(shí),程序就會(huì)處于癱瘓狀態(tài),也很難查找錯(cuò)誤,給編程帶來(lái)了很大的難度,這是多線(xiàn)程數(shù)據(jù)交互今后亟待解決的問(wèn)題。但是整體上,多線(xiàn)程技術(shù)仍然是最具優(yōu)勢(shì)的一項(xiàng)技術(shù),是很有發(fā)展前景的技術(shù)。</p><p> 本文所述工作由于作者水平有限,對(duì)有些問(wèn)題未能深入探討,錯(cuò)誤與不妥之處在所難免,敬請(qǐng)各位老師和同學(xué)給予批評(píng)和指正。</p>
113、;<p><b> 參考文獻(xiàn)</b></p><p> [1] Gropp W, Thankur R .Thread-safety in an MPI implementation:requirements and analysis[J]. Parrallel Computing, 2007,33(9):595-604</p><p> [2] 路
114、小俊,王在軍. 基于ARM平臺(tái)及嵌入式實(shí)時(shí)操作系統(tǒng)的通信管理機(jī)[J]. 電力系統(tǒng)自動(dòng)化,2007.31(16):94-98</p><p> [3] 張建周,栢嵩. 嵌入式高可靠性通信管理機(jī)的設(shè)計(jì)[J].電力系統(tǒng)自動(dòng)化,2007,31(16):94-98</p><p> [4] 鄭燕飛,余海燕. Linux多線(xiàn)程機(jī)制探討與實(shí)踐[J]. 計(jì)算機(jī)應(yīng)用,2001(1):81-83</
115、p><p> [5] 劉立卿. Linux內(nèi)核源代碼分析[M]. 北京:機(jī)械工業(yè)出版社,2000.505-535</p><p> [6] 鄒治鋒,張曦煌. Linux2.6 進(jìn)程調(diào)度[J]. 嵌入式系統(tǒng)應(yīng)用,2006,24(10):30-31</p><p> [7] 張威 .Linux信號(hào)機(jī)解析[J]. 電腦知識(shí)與應(yīng)用,2006,28(8):30-31<
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 多線(xiàn)程網(wǎng)絡(luò)文件傳輸系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文
- uClinux下的數(shù)據(jù)傳輸與多線(xiàn)程處理.pdf
- linux多線(xiàn)程編程
- 數(shù)據(jù)容錯(cuò)的多核多線(xiàn)程投機(jī)方法研究.pdf
- 多線(xiàn)程數(shù)據(jù)記錄裝置的軟件設(shè)計(jì).pdf
- java多線(xiàn)程編程詳解
- Windows CE下多線(xiàn)程多路播放的設(shè)計(jì).pdf
- 多線(xiàn)程程序數(shù)據(jù)競(jìng)爭(zhēng)靜態(tài)檢測(cè)方法研究.pdf
- POSIX多線(xiàn)程程序中數(shù)據(jù)競(jìng)爭(zhēng)錯(cuò)誤的檢測(cè).pdf
- 基于多線(xiàn)程UI-Model的遠(yuǎn)程實(shí)時(shí)交互教學(xué)系統(tǒng).pdf
- linux操作系統(tǒng)下的多線(xiàn)程編程詳細(xì)解析
- 多線(xiàn)程的內(nèi)存調(diào)度.pdf
- 基于多線(xiàn)程技術(shù)的水泥企業(yè)生產(chǎn)數(shù)據(jù)采集系統(tǒng).pdf
- 基于多線(xiàn)程機(jī)制的數(shù)據(jù)采集系統(tǒng)的實(shí)現(xiàn)設(shè)計(jì).pdf
- 多線(xiàn)程程序數(shù)據(jù)競(jìng)爭(zhēng)檢測(cè)和驗(yàn)證方法研究.pdf
- 不錯(cuò)的delphi多線(xiàn)程編程教程
- 24李后浪實(shí)驗(yàn)五 多線(xiàn)程
- NUMA架構(gòu)下多線(xiàn)程訪存分析系統(tǒng)與實(shí)現(xiàn).pdf
- 多線(xiàn)程環(huán)境下的軟件事務(wù)內(nèi)存模型研究.pdf
- 驗(yàn)證帶有線(xiàn)程動(dòng)態(tài)創(chuàng)建和退出多線(xiàn)程程序.pdf
評(píng)論
0/150
提交評(píng)論