|
1,、進程和線程的區(qū)別
5 b& \0 c6 Y4 \6 S5 l, P/ T# S進程的目的就是擔當分配系統(tǒng)資源(CPU時間,、內(nèi)存等)的基本單位,。線程是進程的一個執(zhí)行流,,是CPU調(diào)度和分派的基本單位,,它是比進程更小的能獨立運行的基本單位,。一個進程由幾個線程組成,線程與同屬一個進程的其他的線程共享進程所擁有的全部資源,。
1 l# m8 G4 n9 ~; d
* C- v5 K$ I B+ g9 D, U$ P地址空間:進程有獨立的地址空間,,包括文本區(qū)域(text region)、數(shù)據(jù)區(qū)域(data region)和堆棧(stack region);一個進程崩潰后,,在保護模式下不會對其它進程產(chǎn)生影響,;線程只是一個進程中的不同執(zhí)行路徑,線程有自己的堆棧和局部變量(在運行中必不可少的資源),,但線程之間沒有單獨的地址空間,,一個線程死掉就等于整個進程死掉。同一進程內(nèi)的線程共享進程的地址空間,。/ r2 U' H9 z& d m8 b
7 E- V; E% k- B/ A* @通信:進程間通信IPC,,線程間可以直接讀寫進程數(shù)據(jù)段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性,。
" F" Y# f3 l; a, R$ i n5 t# p! l) x
調(diào)度和切換:線程上下文切換比進程上下文切換要快得多,。2 U' F: ]6 l6 |
/ }% L: Z' \& K' {9 p, g: f ^$ l/ ^
在多線程OS中,進程不是一個可執(zhí)行的實體,。! N5 x) L) i. J% E7 w
* b2 |$ ~" w* ^. @) ^- X/ W" o v
地址空間:進程內(nèi)的一個執(zhí)行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
8 u2 F7 N- f: Y0 D3 n) G1 T2 u6 ^( _3 U$ D8 k
資源擁有:進程是資源分配和擁有的單位,同一個進程內(nèi)的線程共享進程的資源
' Y& m- J# |2 t. a
' }& q" l* x+ q$ g% ?) i( w線程是處理器調(diào)度的基本單位,但進程不是.
9 p1 v9 _' Z- R/ t5 @$ N8 ~1 n( z: c" j+ }7 T' f2 S* u
二者均可并發(fā)執(zhí)行.4 U& C. _9 h' R
% o6 d4 ~+ y4 o
2,、使用線程原因
8 n. V5 r/ C. Q4 J8 ]" Q8 U. e 在Linux系統(tǒng)下,啟動一個新的進程必須分配給它獨立的地址空間,,建立眾多的數(shù)據(jù)表來維護它的代碼段,、堆棧段和數(shù)據(jù)段,這是一種"昂貴"的多任務工作方式,。而運行于一個進程中的多個線程,,它們彼此之間使用相同的地址空間,共享大部分數(shù)據(jù),,啟動一個線程所花費的空間遠遠小于啟動一個進程所花費的空間,,而且,線程間彼此切換所需的時間也遠遠小于進程間切換所需要的時間,。
, E# h N! t" w 線程間方便的通信機制,。對不同進程來說,,它們具有獨立的數(shù)據(jù)空間,要進行數(shù)據(jù)的傳遞只能通過通信的方式進行,,這種方式不僅費時,,而且很不方便。線程則不然,,由于同一進程下的線程之間共享數(shù)據(jù)空間,,所以一個線程的數(shù)據(jù)可以直接為其它線程所用,這不僅快捷,,而且方便,。. p# Q! Y" b8 P, c. J
t8 r. O7 A" E, E3 v# r7 \
% S0 P$ o" Q+ u* V' ^& n H# N0 |
3、線程操作的函數(shù)
) i3 Z- i B; G& m: p#include <pthread.h>
2 ]. j; l2 O; f6 |int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg); . ?0 B. J! A0 d( H; L4 g$ f& G- p
int pthread_join (pthread_t tid, void ** status); 5 X2 t+ l) Q( _* g9 t6 g1 s/ @
pthread_t pthread_self (void);
( E& d. b1 q$ Q3 ]( k, eint pthread_detach (pthread_t tid); 8 G- ~5 L( |! r. ?2 q8 b
void pthread_exit (void *status);' f2 c. U: [8 S# p9 y# T
: v. H- q1 a2 y! R, B2 xpthread_create:用于創(chuàng)建一個線程,,成功返回0,,否則返回Exxx(為正數(shù))。
4 [0 H' l. d5 h0 Q& G r. ?pthread_t *tid:線程id的類型為pthread_t,,通常為無符號整型,,當調(diào)用pthread_create成功時,通過*tid指針返回,。: h" f; n+ C- x5 ?9 C9 [3 n
) E2 T9 I% L4 I0 `9 n$ Oconst pthread_attr_t *attr:指定創(chuàng)建線程的屬性,,如線程優(yōu)先級、初始棧大小,、是否為守護進程等,。可以使用NULL來使用默認值,,通常情況下我們都是使用默認值,。* X5 {( _+ @ o/ G2 _" E
0 A4 [5 }5 _$ m& {( P9 V9 Gvoid *(*func) (void *):函數(shù)指針func,指定當新的線程創(chuàng)建之后,,將執(zhí)行的函數(shù),。4 `; F ], I" z# n
5 s8 ]0 y& f. qvoid *arg:線程將執(zhí)行的函數(shù)的參數(shù),。嵌入式系統(tǒng)學習意義氣嗚嗚吧久零就易,,如果想傳遞多個參數(shù),請將它們封裝在一個結(jié)構(gòu)體中,。/ k- T2 j/ I) G+ V
* E( D, i5 l4 U# ~% \/ i, T( ]" tpthread_join:用于等待某個線程退出,,成功返回0,否則返回Exxx(為正數(shù)),。. r U, d% G9 N, F- D0 m! Q
pthread_t tid:指定要等待的線程ID# b+ P& U8 M+ {) i. H
6 x% i5 L& b: C( `2 k3 [8 V
void ** status:如果不為NULL,,那么線程的返回值存儲在status指向的空間中(這就是為什么status是二級指針的原因!這種才參數(shù)也稱為“值-結(jié)果”參數(shù)),。
7 L3 G& F1 [0 a# j& B
" r- R7 Z$ z# m7 Xpthread_self:用于返回當前線程的ID,。6 p) i s6 C; {1 X+ X( I0 N# d
pthread_detach:用于是指定線程變?yōu)榉蛛x狀態(tài),就像進程脫離終端而變?yōu)楹笈_進程類似。成功返回0,,否則返回Exxx(為正數(shù)),。變?yōu)榉蛛x狀態(tài)的線程,如果線程退出,,它的所有資源將全部釋放,。而如果不是分離狀態(tài),線程必須保留它的線程ID,,退出狀態(tài)直到其它線程對它調(diào)用了pthread_join,。& b8 P! d# O+ \8 S- C( z3 l
pthread_exit用于終止線程,可以指定返回值,,以便其他線程通過pthread_join函數(shù)獲取該線程的返回值,。$ w# b# R- w9 A8 B; r1 R7 q4 f1 x
void *status:指針線程終止的返回值。
g, [" [: l! h7 t. X/ c6 a
: t/ T; J0 S- _/ ]3 M4,、線程間互斥
6 G- l; N4 U$ v6 q# Z 使用互斥鎖(互斥)可以使線程按順序執(zhí)行,。通常,互斥鎖通過確保一次只有一個線程執(zhí)行代碼的臨界段來同步多個線程,�,;コ怄i還可以保護單線程代碼。
0 J+ E$ U/ A8 ~2 w8 iint pthread_mutex_lock(pthread_mutex_t * mptr);
& a& J0 V& t! h% @! w2 V- Cint pthread_mutex_unlock(pthread_mutex_t * mptr);
/ L) G0 ^ N9 T" h6 x& O( S* @! O! m# B$ U9 a
先聲明一個pthread_mutex_t類型的變量,,用作下面兩個函數(shù)的參數(shù),。在對臨界資源進行操作之前需要pthread_mutex_lock先加鎖,操作完之后pthread_mutex_unlock再解鎖,。
- H' {0 r8 L) ^9 L7 l+ H- Z2 X/ e) j; z
. g5 }, h5 s0 h* u6 O
9 S* D: K7 i" O' ]8 J, r7 Q5,、線程間同步
9 J% O+ ^8 W# @條件變量:使用條件變量可以以原子方式阻塞線程,直到某個特定條件為真為止,。條件變量始終與互斥鎖一起使用,。對條件的測試是在互斥鎖(互斥)的保護下進行的。
4 F9 u8 O6 u! V* Y/ w7 D' t#include <pthread.h> 5 [1 u1 n( u5 H2 \( W
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr); 1 n+ ?6 c( \& A6 Z Q( H
int pthread_cond_signal(pthread_cond_t *cptr); : n6 K) _% B, `8 [0 _0 u; |
//Both return: 0 if OK, positive Exxx value on error
, J# T Z% r% ]" i$ D, y3 ~+ c3 |' r1 x7 s9 R7 W
pthread_cond_wait用于等待某個特定的條件為真,,pthread_cond_signal用于通知阻塞的線程某個特定的條件為真了,。在調(diào)用者兩個函數(shù)之前需要聲明一個pthread_cond_t類型的變量,用于這兩個函數(shù)的參數(shù),。
! a3 U5 u8 ^/ `/* / K3 U3 A4 [ [7 B( f8 N4 k
是否熟悉POSIX多線程編程技術(shù),?如熟悉,編寫程序完成如下功能:
" |+ s) r. r( B 1)有一int型全局變量g_Flag初始值為0,; 8 K+ F9 L0 Q; x- m- Z
2)在主線稱中起動線程1,,打印“this is thread1”,并將g_Flag設置為1 1 j9 _& p9 }" H2 F0 z
3)在主線稱中啟動線程2,,打印“this is thread2”,,并將g_Flag設置為2 ! |$ S* h/ D) T4 [2 l0 a9 [
4)線程序1需要在線程2退出后才能退出 , ?5 A- J4 F0 W2 \. L" u9 d
5)主線程在檢測到g_Flag從1變?yōu)?,,或者從2變?yōu)?的時候退出
$ Z" Y/ ^( K7 m1 Q% n$ e6 b |
|