

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p><b> 摘要</b></p><p> 隨著嵌入式Linux系統(tǒng)的廣泛應用和發(fā)展,多線程技術日益完善。使用多線程編程可以大大增進效率。將任務相關聯(lián)的各個線程運行在統(tǒng)一地址空間上,并且共享全局變量和內存,這樣線程之間共享數(shù)據(jù)很方便,相互間通信也容易,十分利于多線程間的數(shù)據(jù)交互。同時,由于ARM與Linux系統(tǒng)的出色表現(xiàn),基于ARM的Linux嵌入式系統(tǒng)的多線程數(shù)據(jù)交互在
2、實際應用得到很好的推廣,多線程數(shù)據(jù)交互的性能也越來越受到重視[1][2][10]。研究如何測試分析多線程間數(shù)據(jù)交互問題以及數(shù)據(jù)交互的方式方法十分有意義。這能為多線程的編程提供很好的參考。</p><p> 本文著重研究多線程下數(shù)據(jù)交互的方式方法,并且測試各種數(shù)據(jù)交互方式的系統(tǒng)性能以及優(yōu)缺點。主要探討了基于互斥鎖的多線程數(shù)據(jù)交互方式、基于條件變量的多線程數(shù)據(jù)交互方式以及基于讀寫鎖的多線程數(shù)據(jù)交互方式。通過設計綜合
3、程序,創(chuàng)建六個線程,分別實現(xiàn)消費者、生產(chǎn)者、讀取、寫入數(shù)據(jù)等功能,相互間采用不同的方式方法進行數(shù)據(jù)交互,以此來研究多線程數(shù)據(jù)交互的編程,測試多線程數(shù)據(jù)交互的性能。整個設計采用C語言,并且調用線程標準庫pthread。以此完成整個設計研究。</p><p> 關鍵詞: Linux; 多線程;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ā)展,多線程編程技術的應用越來越廣泛。特別是在嵌入式系統(tǒng)中存在大量的數(shù)據(jù)交互,采用多線程技術就具有得天獨厚的數(shù)據(jù)交互優(yōu)勢[3]。因此,總結多線程中數(shù)據(jù)交互的方式,分析數(shù)據(jù)交互的性能具有重要的意義。</p><p> 1.1研
10、究背景和意義</p><p> 在嵌入式系統(tǒng)高速發(fā)展的同時,各種新型的編程技術猶如雨后春筍般出現(xiàn)。多線程編程技術在誕生時就一直受到較高的關注,并經(jīng)過多方的改進,確定了POSIX多線程標準,并不斷發(fā)展完善[9]。</p><p> 在實際應用中,一個采用了多線程技術的應用程序可以更好地利用系統(tǒng)資源。其主要優(yōu)勢在于充分利用了CPU的空閑時間片,可以用盡可能少的時間來對用戶的要求做出響應,使
11、得進程的整體運行效率得到較大提高,同時增強了應用程序的靈活性[4]。更為重要的是,由于同一進程的所有線程是共享同一內存,所以不需要特殊的數(shù)據(jù)傳送機制,不需要建立共享存儲區(qū)或共享文件,從而使得不同任務之間的協(xié)調操作與運行、數(shù)據(jù)的交互、資源的分配等問題更加易于解決。多線程數(shù)據(jù)交互采用的是共享內存,因而存在互斥與同步操作。POSIX標準提供標準線程庫pthread。線程庫中有各種線程同步的方法,這方便了線程間的數(shù)據(jù)交互。</p>
12、<p> 本文在總結多線程互斥與同步操作的基礎上,設計程序測試多線程數(shù)據(jù)交互的性能。分析在采用多線程進行數(shù)據(jù)交互過程中,各種互斥與同步操作的數(shù)據(jù)交互的效率與資源占用情況。對比各種多線程數(shù)據(jù)交互的方式方法,能為多線程程序設計提供良好的參考。</p><p><b> 1.2論文組織</b></p><p> 本文設計中以Linux操作系統(tǒng)作為嵌入式系統(tǒng)
13、的研究對象,分析多線程程序設計中各種線程互斥與同步操作,并設計程序,測試多線程數(shù)據(jù)交互的性能,生成總結報告。</p><p> 本文主要由四部分組成:</p><p> 第一部分:介紹論文的研究背景、主要內容及組織方式。</p><p> 第二部分:總結多線程數(shù)據(jù)交互中的各種互斥與同步方式,并分析各種方式的實現(xiàn)過程以及存在的優(yōu)缺點。</p>&l
14、t;p> 第三部分:選取在多線程數(shù)據(jù)交互過程中需要測試的性能的指標以及測試軟件選擇和基本的操作。</p><p> 第四部分:對于各種互斥與同步方法設計相應的測試程序,觀察測試結果,分析產(chǎn)生結果的原因。在此基礎上設計綜合測試程序,進一步分析制約多線程數(shù)據(jù)交互性能的瓶頸。</p><p> 2多線程數(shù)據(jù)交互方法</p><p> 多線程數(shù)據(jù)交互的方法比較
15、成熟,數(shù)量眾多。進行多線程編程時,最應注意的就是數(shù)據(jù)交互中共享數(shù)據(jù)的問題。因為無法知道哪個線程會在哪個時候對共享數(shù)據(jù)進行操作,也無法知道哪個線程先運行,哪個線程后運行。在一般的多線程數(shù)據(jù)交互中,可以將線程看做進程來進行數(shù)據(jù)間的通信[5][7][9]。當然,線程有自己獨有的多線程數(shù)據(jù)交互的方法,主要有互斥鎖方式、條件變量方式、讀寫鎖方式、線程信號方式。</p><p> 2.1使用互斥鎖進行數(shù)據(jù)交互</p&
16、gt;<p> 2.1.1 互斥鎖基本原理</p><p> 互斥鎖是最基本也是最簡單的數(shù)據(jù)交互方式?;コ怄i能夠保證數(shù)據(jù)排他性的訪問,確保了數(shù)據(jù)的安全性。不過互斥鎖交互數(shù)據(jù)中,線程之間申請互斥鎖中會有沖突產(chǎn)生。因而需要在線程解鎖后進行延時。保證其他線程能夠申請到互斥鎖。這降低了線程間通信的效率。影響系統(tǒng)性能[4][7][9][11]。</p><p> 互斥鎖以排他方式
17、防止共享數(shù)據(jù)被并發(fā)修改。互斥鎖是一個二元變量,其狀態(tài)為開鎖和上鎖狀態(tài)。</p><p> 在訪問共享資源中,首先申請該互斥鎖,如果該互斥鎖處于開鎖狀態(tài),則申請到該鎖對象,并立即占有該資源,以防止其他線程訪問該資源;如果該互斥鎖處于鎖定狀態(tài),默認阻塞等待。并且,只有鎖定該互斥鎖的進程才能釋放該互斥鎖。其他線程的釋放操作無效。這樣,容易產(chǎn)生死鎖現(xiàn)象,編程時需要考慮到鎖的各種情況,防止死鎖。</p>&
18、lt;p> 2.1.2互斥鎖數(shù)據(jù)交互方法</p><p> 互斥鎖數(shù)據(jù)交互主要流程包括:使用庫函數(shù)pthread提供的pthread_mutex_init對互斥鎖初始化,以此確定互斥鎖的屬性。在讀寫數(shù)據(jù)時,使用函數(shù)pthread_mutex_lock對互斥鎖上鎖,進而能對數(shù)據(jù)進行排他性訪問。當對數(shù)據(jù)運算完成后,需要使用函數(shù)pthread_mutex_unlock進行解鎖,使其他的線程可以申請到該鎖。最后
19、,當使用完成后,需要函數(shù)pthread_mutex_destroy來銷毀互斥鎖。有時,為了避免死鎖情況,可以采用函數(shù)pthread_mutex_trylock來判斷是否上鎖。</p><p> 互斥鎖的操作使用簡單,能夠為多線程間數(shù)據(jù)的交互提供很好的支持。而且,工作過程穩(wěn)定,不需要另外的設計算法。是多線程數(shù)據(jù)交互很好的選擇。</p><p> 2.2使用條件變量進行數(shù)據(jù)交互</p
20、><p> 2.2.1 條件變量基本原理</p><p> 條件變量是互斥鎖的補充,互斥鎖能夠解決資源的互斥訪問,但互斥鎖一個明顯的缺點是它只有兩種狀態(tài):鎖定和非鎖定。而條件變量通過允許線程阻塞和等待另一個線程發(fā)送信號的方法彌補了互斥鎖的不足,它常和互斥鎖一起使用。條件變量的使用能夠很好的實現(xiàn)數(shù)據(jù)的交互,在多線程數(shù)據(jù)交互中具有很好的實用價值[4][5]。</p><p&
21、gt; 條件變量是互斥鎖的擴充,定義一個條件變量后,需要定義對應的互斥鎖。條件變量被用來阻塞一個線程,當條件不滿足時,線程往往解開相應的互斥鎖并等待條件發(fā)生變化。一旦其它的某個線程改變了條件變量,它將通知相應的條件變量喚醒一個或多個正被此條件變量阻塞的線程。這些線程將重新鎖定互斥鎖并重新測試條件是否滿足[15]。</p><p> 2.2.2 條件變量操作過程</p><p> 使用
22、條件進行數(shù)據(jù)交互時,首先,使用函數(shù)pthread_cond_init初始化條件變量,并且要初始化相應的互斥鎖。然后鎖定互斥鎖,并調用函數(shù)pthread_cond_wait阻塞等待條件變量,同時會解開互斥鎖。當其他線程調用函數(shù)pthread_cond_signal通知等待該條件變量的第一個線程時,阻塞取消,線程繼續(xù)執(zhí)行。當程序運行完后,調用函數(shù)pthread_cond_destroy銷毀條件變量。也可調用函數(shù)pthread_cond_ti
23、medwait函數(shù)在指定的時間內阻塞等待條件變量。當有多個線程等待變量時,可以調用函數(shù)pthread_cond_broadcast函數(shù)通知等待該條件變量的所有線程。</p><p> 條件變量的操作相對互斥鎖是比較復雜的,但是能夠完成更多的數(shù)據(jù)交互,并且,由于條件變量采用的是通知等待的模式,因而在數(shù)據(jù)交互處理中更加的方便靈活,效率也比互斥鎖要高。是多線程編程中數(shù)據(jù)交互和同步很好的選擇。</p>&
24、lt;p> 2.3使用讀寫鎖進行數(shù)據(jù)交互</p><p> 2.3.1 讀寫鎖基本原理</p><p> 在對數(shù)據(jù)的讀寫應用中,更多的操作是讀操作,而寫操作較少,例如對數(shù)據(jù)庫函數(shù)的讀寫應用,為了滿足當前能夠允許多個讀寫,但只允許一個寫入的需求,線程提供了讀寫鎖來實現(xiàn)。</p><p> 在數(shù)據(jù)交互過程中,如果有其它線程讀數(shù)據(jù),則允許其他線程執(zhí)行讀操作,
25、但不允許寫操作;如果有其它線程寫數(shù)據(jù),則其它線程的讀、寫操作均允許。</p><p> 在讀寫鎖過程中,如果某線程申請了讀鎖,其他線程可以再申請讀鎖,但不能申請寫鎖。如果某線程申請了寫鎖,則其它線程不能申請讀鎖,也不能申請寫鎖。</p><p> 2.3.2 讀寫鎖操作過程</p><p> 在使用讀寫鎖過程中,首先,調用函數(shù)pthread_rwlock_in
26、it初始化讀寫鎖。當需要讀取數(shù)據(jù)時,可以調用函數(shù)pthread_rwlock_rdlock阻塞申請讀鎖,這個時候仍然可以再申請讀鎖,但是不能夠申請寫鎖。在需要寫數(shù)據(jù)的時候,可以調用函數(shù)pthread_rwlock_wrlock阻塞申請寫鎖,當申請到寫鎖后,就不能再申請到讀鎖,也不能申請寫鎖。在讀寫鎖完成后,可以調用函數(shù)pthread_rwlock_unlock來釋放鎖,在不需要讀寫鎖后,應調用函數(shù)pthread_rwlock_destr
27、oy來銷毀讀寫鎖。在申請讀寫鎖過程中,可以分別調用函數(shù)pthread_rwlock_trywrlock和函數(shù)pthread_rwlock_tryrdlock函數(shù)來進行非阻塞申請讀鎖和非阻塞申請寫鎖。</p><p> 讀寫鎖是基于實際操作中的讀多于寫而設計的,在多線程數(shù)據(jù)交互中,能夠避免排他性的讀數(shù)據(jù)而影響整體的性能。同時,讀寫鎖也能夠很好的實現(xiàn)多線程的數(shù)據(jù)交互與同步,具有很好的實用意義。</p>
28、<p> 2.4其它線程數(shù)據(jù)交互方式</p><p> 2.4.1 信號量數(shù)據(jù)交互方式</p><p> 信號量本質上是一個非負的整數(shù)計數(shù)器,它被用來控制對公共資源的訪問。當公共資源增加時,調用函數(shù)sem_post()增加信號量。只有當信號量值大于0時,才能使用公共資源,使用后,函數(shù)sem_wait()減少信號量。函數(shù)sem_trywait()和函數(shù)pthread_ mu
29、tex_trylock()起同樣的作用,它是函數(shù)sem_wait()的非阻塞版本。信號量定義完成了互斥體和條件變量的封裝,按照多線程程序設計中訪問控制機制,控制對資源的同步訪問,提供程序設計人員更方便的調用接口[12]。</p><p> 2.4.2 線程與信號數(shù)據(jù)交互方式</p><p> 線程與擁有與信號相關的私有數(shù)據(jù)---線程信號掩碼,這樣,線程可以使用信號操作來實現(xiàn)數(shù)據(jù)的同步,
30、每個線程可也向別的線程發(fā)送信號,每個線程可以設置自己的信號阻塞集合并設置針對某信號的處理方式,但同一進程中對某信號的處理方式只能有一個有效,即最后一次設置的處理方式。如果別的進程向當前進程中發(fā)送一個信號,那么由哪個線程處理則是未知的[6][8][13]。</p><p> 3多線程數(shù)據(jù)性能測試方法</p><p> 多線程數(shù)據(jù)交互中,監(jiān)測系統(tǒng)的性能能夠很好的了解多線程數(shù)據(jù)交互中系統(tǒng)存在
31、的瓶頸以及采用數(shù)據(jù)交互方法存在的部分問題。在普通的Linux系統(tǒng)監(jiān)測中,主要包括正在執(zhí)行的進程、內存的使用率、磁盤的性能、網(wǎng)絡流量和CPU的壓力。由于多線程數(shù)據(jù)交互中,系統(tǒng)負載不會改變,而又不涉及到網(wǎng)絡和磁盤。因此,選擇CPU性能、內存使用率以及正在運行的進程作為監(jiān)測的指標[12][14][15]。</p><p> 3.1 CPU性能測試</p><p> CPU是電腦的核心硬件,C
32、PU的使用情況對程序的設計有很好的指導作用。在觀察多線程數(shù)據(jù)交互中,使用top命令來觀察CPU的運行。其顯示結果如圖3.1.1所示。</p><p> 圖3.1.1 top命令運行界面</p><p> 在圖中,CPU性能主要觀測第三行,us表示用戶空間占用CPU百分比,sy表示內核空間占用CPU百分比,ni表示用戶進程空間內改變過優(yōu)先級的進程占用CPU百分比,id表示空閑CPU百分比
33、,wa表示等待輸入輸出的CPU時間百分比,hi表示硬中斷,si表示軟中斷。</p><p> 在界面第一行中,包含用戶登錄時間,當前用戶數(shù)和系統(tǒng)在一分鐘、五分鐘、十五分鐘內的平均負載。第二行中,包含了系統(tǒng)進程總數(shù)、正在運行、睡眠、僵尸、停止的進程數(shù)。而第四行中,包含物理內存總量、使用的物理內存總量、空閑物理內存總量以及用作內核緩存的內存量。最后是進程信息區(qū),包含了進程的ID、父進程的ID以及CPU的占用率。&l
34、t;/p><p><b> 3.2內存性能測試</b></p><p> 內存是Linux內核所有管理的重要資源之一,內存管理系統(tǒng)是操作系統(tǒng)中的重要部分。在觀察多線程數(shù)據(jù)交互中,采用free命令來監(jiān)控內存使用情況。其界面如圖3.2.1所示。</p><p> 圖3.2.1 free命令界面</p><p> 其中,M
35、em表示物理內存統(tǒng)計,包括總共物理內存,使用的內存,空閑內存空間。-/+buffer/cached表示物理內存的緩存統(tǒng)計。Swap表示硬盤上交換分局的使用情況。在多線程數(shù)據(jù)交互中,主要關注物理內存統(tǒng)計情況。</p><p> 對于單獨程序而言,可以使用命令“pmap –x +進程ID”來獲得進程使用內存的情況,輸入命令后,其界面圖如下所示:</p><p> 圖3.2.2 命令pmap
36、界面圖</p><p> 由上圖可以得出,程序two_change總共占用內存空間為22196KB。并且,可以了解每一個Mapping對應映像名的起始地址。是觀察單獨進程內存使用情況很好的工具。</p><p><b> 3.3進程運行測試</b></p><p> 系統(tǒng)進程的運行對于分析系統(tǒng)的各項指標具有重要的意義,觀察進程對系統(tǒng)資源的
37、占用能更好的理解多線程數(shù)據(jù)交互過程以及性能。對于系統(tǒng)進程的觀察,采用圖形界面軟件KDE System Guard ,其界面圖如圖3.3.1所示。</p><p> 圖3.3.1 KDE System Guard界面</p><p> 根據(jù)圖形界面顯示,在進程表中可以選擇“樹”形顯示,能夠清楚的了解系統(tǒng)進程的關系。在進程列表中,可以查看進程的狀態(tài)、進程ID以及父進程等信息。能夠了解線程占
38、用CPU比例??梢院芎玫姆治鼍€程的運行情況。</p><p> 由于圖形界面占用較多的系統(tǒng)資源,在觀察程序運行中,可以簡單的使用“ps –all” 命令,得到如下圖所示界面:</p><p> 圖3.3.2 ps命令界面圖</p><p> 從圖中,可以獲得程序two_change的進程ID 為7638.這樣,結合top命令和pmap命令,能夠很容易的獲得進程
39、ID為7638所占用的CPU和內存等系統(tǒng)資源。方便對多線程程序的測試分析。</p><p> 4測試步驟及結果分析</p><p> 通過分析多線程數(shù)據(jù)交互的各種方法,在總結成熟技術基礎上,設計程序,分析程序運行結果,測試多線程數(shù)據(jù)交互中系統(tǒng)的性能。測試方法采用ps、top、pmap命令,觀察CPU使用率、內存使用率以及進程運行情況。</p><p> 4.1
40、基于互斥鎖的設計思路及測試結果</p><p> 4.1.1互斥鎖程序設計思路</p><p> 利用互斥鎖進行數(shù)據(jù)交互是基于互斥鎖在鎖定后,只有鎖定互斥鎖的線程能夠對數(shù)據(jù)進行訪問,而其他的線程需要等待線程解鎖后才能進行數(shù)據(jù)的訪問。這樣,利用互斥鎖就能完成多線程間數(shù)據(jù)交互,避免沖突。</p><p> 設計思路上,首先創(chuàng)建兩個線程,一個甲線程用于產(chǎn)生隨機數(shù)據(jù)并
41、寫入指定文件和賦值給全局變量,另一個乙線程用于處理甲線程產(chǎn)生的數(shù)據(jù),具體功能圖和程序流程圖如圖4.1.1、4.1.2所示。</p><p> 圖4.1.1 互斥鎖數(shù)據(jù)交互設計圖</p><p> 圖4.1.2 互斥鎖程序設計流程圖</p><p> 線程甲、乙是并行執(zhí)行。主線程調用pthread_join()函數(shù)來阻塞等待線程甲、乙結束。線程甲調用data_p
42、roduce()函數(shù)來產(chǎn)生隨機數(shù)據(jù),并且將產(chǎn)生的隨機數(shù)據(jù)傳遞給全局變量temp。線程乙調用data_handle()處理數(shù)據(jù),對全局變量temp的數(shù)據(jù)進行數(shù)學運算。整個數(shù)據(jù)交互過程采用全局變量的方式來傳遞數(shù)據(jù)。部分源程序如下所示。</p><p> 線程甲產(chǎn)生隨機數(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ù)是一個死循環(huán)過程,不停的使用鎖定互斥量data_mutex來對全局變量temp進行排他性訪問。在賦值完成后,再解鎖,并且等待1s中,以便其他線程獲取互斥量而對數(shù)據(jù)進行讀取。</p>
46、<p> 線程乙讀取全局變量數(shù)據(jù),并且進行簡單處理,其函數(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ù)進行運算賦值。而為確保數(shù)據(jù)交互的可靠性,在讀取數(shù)據(jù)前執(zhí)行鎖定互斥量data_mutex的操作。當甲線程鎖定互斥量后,乙線程將阻塞等待,同樣,甲線程在乙線程鎖定互斥量后也會阻塞等待。乙在讀取處理
50、完數(shù)據(jù)后會解鎖,此時,等待上鎖的甲線程會立即獲得互斥鎖。這樣就保證了數(shù)據(jù)能夠正確的讀取和處理。</p><p> 4.1.2互斥鎖數(shù)據(jù)交互測試結果</p><p> 通過分析程序,在線程乙中,插入變量num,每次處理完數(shù)據(jù)后都進行加一操作,并顯示num變量值。同樣,在線程甲中定義變量i,進行同樣的操作,程序運行結果如下:</p><p> 圖4.1.3 互斥鎖
51、程序運行結果</p><p> 根據(jù)上圖結果表明,總會有兩個同樣的數(shù)據(jù)顯示,一個是甲線程中的變量i,一個是乙線程中的變量num,兩個線程在各自線程每運行一次都會加一并且打印結果。因此可知,線程甲、乙交替運行,全局變量temp在甲線程賦值后很快被乙線程讀取數(shù)據(jù),在讀取數(shù)據(jù)后,甲線程才再次給temp賦值,整個實現(xiàn)過程沒有沖突出現(xiàn)?;コ怄i進行數(shù)據(jù)交互中,能夠很好的完成數(shù)據(jù)的交互。</p><p&g
52、t; 采用top命令,觀察進程PID為7197的運行狀態(tài),即調試程序的運行??芍?,CPU占用率為3.0%,內存使用了502M。</p><p> 圖4.1.4 互斥鎖測試程序結果</p><p> 根據(jù)上述top命令結果分析,由于互斥鎖操作中,需要等待操作,而等待操作過程中,CPU空閑,因此,CPU的使用率十分的低,調用pmap命令查看程序運行單獨內存,內存占用大小為22200KB,
53、說明使用互斥鎖進行數(shù)據(jù)交互過程中,對系統(tǒng)資源占用十分的少,主要占用的是內存資源。當去掉等待時間時。部分源程序如下。</p><p> 甲線程修改后函數(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> 在修改中,去掉了等待時間,并且在互斥操作中對互斥鎖data_mutex進行一萬次的重復操作,并且在解鎖操作后不去等待而直接的進行上鎖操作。</p><p> 線程乙數(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> 線程乙處理數(shù)據(jù)也沒有加入等待操作,直接對互斥量進行上鎖和解鎖操作,這樣,在上鎖過程中,甲線程和乙線程上鎖就是隨機競爭的。這不能保證當甲線程產(chǎn)生數(shù)據(jù)后,乙線程能夠立即的對數(shù)據(jù)進行處理,相反,甲線程幾乎會一直占有互斥鎖,而乙線程會一直的
61、阻塞等待。 </p><p> 運行改編后的程序,結果如下:</p><p> 圖4.1.5 無等待時間運行結果</p><p> 根據(jù)結果顯示,線程甲和線程乙在任意一個占用互斥鎖后,會一直的占用,并且不停的運行,直到下次另一個線程搶占到互斥鎖。這樣,線程間的數(shù)據(jù)交互就會出現(xiàn)不同步的問題。這對數(shù)據(jù)交互來說,是十分危險的。因此,在使用互斥鎖過程中,插入等待
62、時間是有必要的。</p><p> 通過調用top命令,可觀察得到新的檢測圖如圖4.1.6所示。</p><p> 圖4.1.6 無等待時間系統(tǒng)狀態(tài)</p><p> 由top命令的監(jiān)測結果可知,系統(tǒng)運行的在滿負荷狀態(tài),CPU占用率達到95.0%,內存也使用在滿負荷狀態(tài),但是,由于沒有系統(tǒng)等待,很多互斥鎖的申請一直由某一個線程占有,而其它線程阻塞等待。整個申請
63、搶占互斥鎖是隨機的過程,存在很大的數(shù)據(jù)交換問題。內存占用大小為22196KB。相對于含有等待時間的互斥鎖數(shù)據(jù)交互而言,內存變化不大,這說明對于基于互斥鎖的多線程數(shù)據(jù)交互過程,CPU的負載主要是用于線程內部的數(shù)據(jù)處理,而線程間的切換和同步,并不占用過多的CPU資源。</p><p> 4.2基于條件變量的設計思路及測試結果</p><p> 4.2.1 條件變量程序設計思路</p&
64、gt;<p> 基于條件變量的程序設計是創(chuàng)建兩個線程,一個生產(chǎn)者線程,一個消費者線程。并且定義一個具有兩個緩存區(qū)的結構體,生產(chǎn)者線程寫入數(shù)據(jù),消費者線程讀取數(shù)據(jù)。通過條件變量和互斥鎖結合使用,實現(xiàn)數(shù)據(jù)的交互。具體工作過程如圖4.2.1所示。</p><p> 圖4.2.1 條件變量數(shù)據(jù)交互設計圖</p><p> 由圖可知,與基于互斥鎖的數(shù)據(jù)交互相比,基于條件變量的數(shù)據(jù)
65、交互設計添加了等待非空、非滿信號。利用這種機制,可以很好的實現(xiàn)數(shù)據(jù)交互中的問題。在具體實現(xiàn)過程中,定義一個結構體buffer作為臨時的緩存區(qū),用put函數(shù)向緩存區(qū)寫入數(shù)據(jù),當寫入數(shù)據(jù)完成后,將發(fā)送非空條件變量,當寫滿后阻塞等待非滿條件變量;用get函數(shù)讀取臨時變量,當讀取一個數(shù)據(jù)后,將發(fā)送非滿條件變量,當讀取完所有數(shù)據(jù)后阻塞等待非空條件變量。而消費者線程循環(huán)調用get函數(shù),生產(chǎn)者線程循環(huán)調用put函數(shù)。部分源程序如下。</p>
66、;<p> 臨時緩存區(qū)結構體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、/讀寫位置</p><p> pthread_cond_t notempty;//非空條件變量</p><p> pthread_cond_t notfull;//非滿條件變量</p><p><b> } ; </b></p><p> struct prodcons buffer;</p>&l
68、t;p> 在buffer結構體中,定義了一個兩位數(shù)的一維數(shù)組buffer[]作為數(shù)據(jù)緩存區(qū);并且定義了互斥鎖和兩個條件變量分別表示非空和非滿;為了便于判斷,定義了讀位置和寫位置兩個變量,表示讀寫數(shù)組的位置。</p><p> 生產(chǎn)者調用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)者調用put函數(shù)后,將隨機數(shù)據(jù)傳遞給data,并且將定義的緩存區(qū)buffer傳遞給put函數(shù)。進入put函數(shù)后,首先判斷buffer是否已滿,當buffer已滿后會阻
73、塞等待,直到消費者線程發(fā)送未滿條件變量。收到信號后,會向buffer寫入數(shù)據(jù),并且發(fā)送非空條件變量,激活等待非空條件變量的線程。并且改變寫位置變量值。</p><p> 消費者調用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> 在消費者調用get函數(shù)后,與put函數(shù)相似。會
78、判斷非空并且會阻塞等待非空信號。當讀取數(shù)據(jù)后,將數(shù)據(jù)返回給消費者,并且發(fā)送非滿條件變量。激活等待非滿條件變量的線程。一般情況下,消費者與生產(chǎn)者都會出現(xiàn)阻塞等待情況。</p><p> 4.2.2 條件變量數(shù)據(jù)交互測試結果</p><p> 運行程序,其結果如下:</p><p> 圖4.2.2 條件變量程序運行結果</p><p>
79、由結果分析可知,生產(chǎn)者線程放入一個數(shù)據(jù)后,消費者線程讀取一個數(shù)據(jù);之后生產(chǎn)者連續(xù)放入兩個數(shù)據(jù),然后阻塞等待非滿條件變量。當消費者線程讀取一個數(shù)據(jù)后,生產(chǎn)者線程接著放入數(shù)據(jù),如此循環(huán),能夠保證生產(chǎn)者消費者數(shù)據(jù)交互高效進行。</p><p> 通過調用top命令,觀察程序運行情況如圖4.2.3所示。</p><p> 圖4.2.3 條件變量數(shù)據(jù)交互測試結果</p><p
80、> 程序運行時CPU占用率占用率很低,內存占用大小為22204KB。這說明基于條件變量的多線程數(shù)據(jù)交互對系統(tǒng)要求很低。主要是對內存資源占用大。</p><p> 4.3基于讀寫鎖與線程信號的設計思路及測試結果</p><p> 4.3.1 讀寫鎖程序設計思路</p><p> 基于讀寫鎖程序設計是創(chuàng)建四個線程,兩個讀線程,兩個寫線程。兩個寫線程向數(shù)組中
81、寫入數(shù)據(jù),并且分別申請寫鎖,防止寫入數(shù)據(jù)沖突;兩個讀線程同時讀取寫入的數(shù)據(jù),并且競爭。當寫線程申請到寫鎖后讀線程將被阻塞,同時另一個寫線程也被阻塞。而申請到讀線程后,另一個讀線程也可以申請讀鎖,但是寫線程被阻塞。具體功能圖如圖4.3.1所示。</p><p> 圖4.3.1 基于讀寫鎖的程序設計</p><p> 程序實現(xiàn)方式與互斥鎖實現(xiàn)方式相似,通過調用thread_function
82、_read_o()函數(shù)來讀數(shù)據(jù),通過調用thread_function_write_o()函數(shù)來向緩存數(shù)組寫入數(shù)據(jù)。讀寫操作均需要調用讀寫鎖來保證共享數(shù)據(jù)能夠實現(xiàn)安全訪問。部分源代碼如下所示。</p><p> 寫線程甲函數(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> 進入寫線程后,首先鎖定讀寫鎖,防止其它讀線程或者寫線程修改數(shù)據(jù),然后向緩存數(shù)
86、組寫入數(shù)據(jù),在寫操作完成后,解開讀寫鎖,并且進入休眠,將讀寫鎖交給其它線程。在休眠3秒鐘后再次搶占讀寫鎖。</p><p> 讀線程甲的函數(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> 讀線程與寫線程操作相似,讀線程可以有多個同時申請讀鎖,但是申請到讀鎖后,寫鎖就被阻塞。</p><p> 4
90、.3.2 讀寫鎖數(shù)據(jù)交互測試結果</p><p> 運行程序,結果如下所示:</p><p> 圖4.3.2 讀寫鎖程序運行結果</p><p> 由結果可知,寫線程甲在申請到寫鎖后,向數(shù)組位置0、1寫入數(shù)據(jù),而寫線程乙在之后申請到寫鎖,并向位置2寫入數(shù)據(jù)。讀鎖是同時進行的,當寫鎖解鎖后,讀線程甲、乙都可以申請讀線程,并且顯示出寫入的數(shù)據(jù)。不存在讀線程相互阻塞
91、。但是當有寫線程申請到寫鎖時,讀線程阻塞,同樣,在有讀線程申請到讀鎖時,寫線程也會阻塞。這樣,寫入數(shù)組的數(shù)據(jù)能夠保證順序無重復的寫入,而且能夠被多次讀取。</p><p> 運行程序,調用top命令,得到線程運行狀態(tài)如圖4.3.3所示。</p><p> 圖4.3.3 讀寫鎖數(shù)據(jù)交互測試結果</p><p> 同樣,基于共享變量的機制,讀寫鎖占用系統(tǒng)資源也十分
92、的少,程序運行過程中CPU、內存占用率都十分的低。通過調用pmap命令,可得程序內存占用大小為42688KB。這相對于互斥鎖與條件變量來說,是兩倍的差距,而這次創(chuàng)建了四個線程,之前的程序只是創(chuàng)建了兩個線程,但是CPU的使用率依舊非常的低,這說明,在多線程數(shù)據(jù)交互中,CPU的使用率只是與線程中數(shù)據(jù)運算的多少有關,而與線程的多少和數(shù)據(jù)交互多少無關。但是,內存的多少卻是隨著線程的增加而增加。</p><p> 4.4
93、整體數(shù)據(jù)交互方法設計思路與測試結果</p><p> 4.4.1整體數(shù)據(jù)交互程序設計思路</p><p> 在前期設計的基礎上,設計中采用互斥鎖、條件變量及讀寫鎖綜合設計程序。程序設計了六個線程。由生產(chǎn)者線程向緩沖區(qū)寫入數(shù)據(jù),消費者線程讀取數(shù)據(jù),并且由兩個寫線程同時向數(shù)組中寫入數(shù)據(jù)。同時兩個讀線程一起讀取寫入的數(shù)據(jù)。整體流程圖如圖4.1.1所示。</p><p>
94、; 圖4.4.1 整體設計圖</p><p> 程序設計十分的復雜,數(shù)據(jù)間交互采用了互斥鎖,條件變量以及讀寫鎖方式。生產(chǎn)者消費者線程間采用條件變量進行數(shù)據(jù)交互,消費者與寫線程間采用互斥鎖進行通信,而讀寫線程間采用讀寫鎖進行通信。從而保證程序數(shù)據(jù)交互的安全性。部分源程序如下:</p><p> 消費者線程函數(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> 消費者線程中,添加了互斥量data_mutex,使用互斥鎖,將產(chǎn)生的數(shù)據(jù)傳
100、遞全局變量temp,互斥鎖能夠很好的保證在向temp寫數(shù)據(jù)與讀數(shù)據(jù)時不產(chǎn)生沖突。生產(chǎn)者線程與消費者線程間數(shù)據(jù)同步采用條件變量方式,可以很好的實現(xiàn)生產(chǎn)消費,并且輸出數(shù)據(jù)給其它線程使用數(shù)據(jù)。</p><p> 寫線程甲的函數(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> 寫線程接收數(shù)據(jù),并且將數(shù)據(jù)寫入緩存數(shù)組中。數(shù)據(jù)來自全局變量temp,并且使用互斥鎖,來完成讀寫temp數(shù)據(jù)的安全性。而寫線程與其他讀寫線程間采用讀寫鎖進行同步。在寫線程中,還有寫線程乙,與寫線程甲具有相同的作用。寫線程甲乙相互競爭,向緩存數(shù)據(jù)順序寫入數(shù)據(jù)。讀線程可以同步讀取寫入數(shù)組的
105、數(shù)據(jù)。</p><p> 4.4.2 整體數(shù)據(jù)交互測試結果</p><p> 運行程序,結果如下所示:</p><p> 圖4.4.2 整體程序運行結果</p><p> 根據(jù)結果顯示,所有線程同步運行,但是消費者線程首先被非空條件變量阻塞,讀寫線程比生產(chǎn)者線程提前運行,造成寫入數(shù)據(jù)0號位置的值為0。當生產(chǎn)者線程執(zhí)行后,消費者線程讀取
106、第一個數(shù)據(jù)。寫線程將數(shù)據(jù)寫入數(shù)組,讀線程讀取顯示數(shù)據(jù)。多線程之間數(shù)據(jù)交按照生產(chǎn)、消費、寫入、讀取順序進行,數(shù)據(jù)交互十分良好,沒有出現(xiàn)沖突現(xiàn)象。</p><p> 調用top命令,程序運行狀態(tài)如圖4.4.3所示。</p><p> 圖4.4.3 整體數(shù)據(jù)交互測試結果</p><p> 根據(jù)結果顯示,雖然含有七個線程,并且數(shù)據(jù)交互頻繁,但是程序占用系統(tǒng)資源依然十分
107、的少。CPU占用率和內存使用率也很低。程序運行很好。使用pmap命令查看內存具體使用情況時,內存使用大小為63180KB,占用系統(tǒng)資源十分的少。根據(jù)前面的測試,互斥鎖數(shù)據(jù)交互占用內存22196KB、條件變量數(shù)據(jù)交互內存占用22204KB、讀寫鎖數(shù)據(jù)交互42688KB。系統(tǒng)內存占用情況要少于全部內存的簡單疊加。但是內存占用是比較大得。</p><p> 根據(jù)以上分析,多線程數(shù)據(jù)交互過程中,所占用的CPU資源十分的
108、少,然而內存空間占用相對較多。多線程數(shù)據(jù)交互中,要保證數(shù)據(jù)訪問能安全進行,就需要線程同步,而線程同步過程中,會消耗大量的時間,以至于對CPU資源的使用較少,同時,線程間的數(shù)據(jù)傳遞是采用共享內存的方式進行,對CPU需求較少。然而,對于內存資源,線程間數(shù)據(jù)傳遞會占用較多的內存,這樣,在單純的進行多線程數(shù)據(jù)交互時,對內存的要求遠高于對CPU的要求。</p><p><b> 5總結與展望</b>
109、</p><p> Linux的多線程技術是一項十分前沿的編程技術,而多線程交互數(shù)據(jù)的技術仍然在探索中,基于ARM的多線程數(shù)據(jù)交互的性能是在分析多線程數(shù)據(jù)交互的基礎上,測試多線程數(shù)據(jù)交互中,系統(tǒng)的的資源占用情況。</p><p> 在本文的設計中,通過測試分析,多線程數(shù)據(jù)交互的方式主要有互斥鎖方式、條件變量方式、讀寫鎖方式。每一種多線程數(shù)據(jù)交互的方式CPU占用率十分的少,在設計對比過程
110、中,由于要盡量保證單一變量的方式,因此,不能夠在多線程中進行頻繁的占用CPU操作。而單一的多線程數(shù)據(jù)交互中,線程間數(shù)據(jù)交互由于要采用同步機制,則線程間都需要等待同步,這樣的后果是CPU的使用率明顯的降低。這個問題需要進一步的探索。</p><p> 多線程技術在嵌入式實時系統(tǒng)中具有明顯的優(yōu)勢。線程能夠同步的執(zhí)行,這樣能極大的提高程序的并行性,充分利用多核處理器的資源。由于線程共享進程地址空間內的所有資源,所以線
111、程之間的通信是很方便的。多個線程處理不同的任務,增加了程序的并發(fā)性,是程序更高效的執(zhí)行。這些優(yōu)勢都是多線程技術得到了很大得重視,而多線程的數(shù)據(jù)交換性能在很大程度上影響系統(tǒng)整體的性能。分析多線程數(shù)據(jù)交換的性能,能在一定程度上解決系統(tǒng)的瓶頸問題,使系統(tǒng)能夠更加高效的運行。</p><p> 多線程的數(shù)據(jù)交互技術仍然需要改進,在利用線程同步機制過程中,線程的等待時間過長,這不利于系統(tǒng)的實時性。雖然可以降低等待同步時間
112、,但是容易產(chǎn)生讀寫數(shù)據(jù)沖突或者數(shù)據(jù)不能有序的讀寫。同時,在使用互斥鎖過程中,當出現(xiàn)死鎖問題時,程序就會處于癱瘓狀態(tài),也很難查找錯誤,給編程帶來了很大的難度,這是多線程數(shù)據(jù)交互今后亟待解決的問題。但是整體上,多線程技術仍然是最具優(yōu)勢的一項技術,是很有發(fā)展前景的技術。</p><p> 本文所述工作由于作者水平有限,對有些問題未能深入探討,錯誤與不妥之處在所難免,敬請各位老師和同學給予批評和指正。</p>
113、;<p><b> 參考文獻</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ǒng)的通信管理機[J]. 電力系統(tǒng)自動化,2007.31(16):94-98</p><p> [3] 張建周,栢嵩. 嵌入式高可靠性通信管理機的設計[J].電力系統(tǒng)自動化,2007,31(16):94-98</p><p> [4] 鄭燕飛,余海燕. Linux多線程機制探討與實踐[J]. 計算機應用,2001(1):81-83</
115、p><p> [5] 劉立卿. Linux內核源代碼分析[M]. 北京:機械工業(yè)出版社,2000.505-535</p><p> [6] 鄒治鋒,張曦煌. Linux2.6 進程調度[J]. 嵌入式系統(tǒng)應用,2006,24(10):30-31</p><p> [7] 張威 .Linux信號機解析[J]. 電腦知識與應用,2006,28(8):30-31<
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 多線程網(wǎng)絡文件傳輸系統(tǒng)的設計與實現(xiàn)畢業(yè)論文
- uClinux下的數(shù)據(jù)傳輸與多線程處理.pdf
- linux多線程編程
- 數(shù)據(jù)容錯的多核多線程投機方法研究.pdf
- 多線程數(shù)據(jù)記錄裝置的軟件設計.pdf
- java多線程編程詳解
- Windows CE下多線程多路播放的設計.pdf
- 多線程程序數(shù)據(jù)競爭靜態(tài)檢測方法研究.pdf
- POSIX多線程程序中數(shù)據(jù)競爭錯誤的檢測.pdf
- 基于多線程UI-Model的遠程實時交互教學系統(tǒng).pdf
- linux操作系統(tǒng)下的多線程編程詳細解析
- 多線程的內存調度.pdf
- 基于多線程技術的水泥企業(yè)生產(chǎn)數(shù)據(jù)采集系統(tǒng).pdf
- 基于多線程機制的數(shù)據(jù)采集系統(tǒng)的實現(xiàn)設計.pdf
- 多線程程序數(shù)據(jù)競爭檢測和驗證方法研究.pdf
- 不錯的delphi多線程編程教程
- 24李后浪實驗五 多線程
- NUMA架構下多線程訪存分析系統(tǒng)與實現(xiàn).pdf
- 多線程環(huán)境下的軟件事務內存模型研究.pdf
- 驗證帶有線程動態(tài)創(chuàng)建和退出多線程程序.pdf
評論
0/150
提交評論