|
1,、進(jìn)程和線程的區(qū)別/ A Z" j( V. O( o2 ~
進(jìn)程的目的就是擔(dān)當(dāng)分配系統(tǒng)資源(CPU時(shí)間、內(nèi)存等)的基本單位。線程是進(jìn)程的一個(gè)執(zhí)行流,,是CPU調(diào)度和分派的基本單位,,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位。一個(gè)進(jìn)程由幾個(gè)線程組成,線程與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源,。4 Z& F+ g6 R1 W3 K2 r! a
1 ~2 b$ y0 y* m5 y I$ P/ s地址空間:進(jìn)程有獨(dú)立的地址空間,,包括文本區(qū)域(text region)、數(shù)據(jù)區(qū)域(data region)和堆棧(stack region);一個(gè)進(jìn)程崩潰后,,在保護(hù)模式下不會(huì)對其它進(jìn)程產(chǎn)生影響,;線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑,線程有自己的堆棧和局部變量(在運(yùn)行中必不可少的資源),,但線程之間沒有單獨(dú)的地址空間,,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉。同一進(jìn)程內(nèi)的線程共享進(jìn)程的地址空間,。% z8 S1 v* d4 _8 Q
. v1 G3 o' \9 r' U9 \4 C
通信:進(jìn)程間通信IPC,,線程間可以直接讀寫進(jìn)程數(shù)據(jù)段(如全局變量)來進(jìn)行通信——需要進(jìn)程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性,。) {5 X5 b; d- u+ ~- E t9 s
* i3 K3 o8 }& \& H8 t調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多,。
' ] Z: t9 _/ d) ~; ~" Q& i3 {" n, P1 H" C* A6 r) n
在多線程OS中,進(jìn)程不是一個(gè)可執(zhí)行的實(shí)體,。. X) z& M* Q1 e. Z, Q) D
6 x+ ~6 K2 g% }, I地址空間:進(jìn)程內(nèi)的一個(gè)執(zhí)行單元;進(jìn)程至少有一個(gè)線程;它們共享進(jìn)程的地址空間;而進(jìn)程有自己獨(dú)立的地址空間;8 |, V1 I) p+ n- s \5 Y( F F
2 g! y0 V) j: }9 A# \資源擁有:進(jìn)程是資源分配和擁有的單位,同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程的資源2 Y/ m/ L; N9 R$ K' l" P
# q) H5 c3 X/ z/ j3 X" G+ P
線程是處理器調(diào)度的基本單位,但進(jìn)程不是.3 F$ Y! g4 D8 ~* Q: s
3 k0 y- n8 _ g" _二者均可并發(fā)執(zhí)行.
& \; v& B: X" L t* i \% A: H8 S/ w6 P5 M% _2 r9 }
2,、使用線程原因- [, f6 B; M+ f- t8 _' C) u& l
在Linux系統(tǒng)下,,啟動(dòng)一個(gè)新的進(jìn)程必須分配給它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來維護(hù)它的代碼段,、堆棧段和數(shù)據(jù)段,,這是一種"昂貴"的多任務(wù)工作方式。而運(yùn)行于一個(gè)進(jìn)程中的多個(gè)線程,,它們彼此之間使用相同的地址空間,,共享大部分?jǐn)?shù)據(jù),啟動(dòng)一個(gè)線程所花費(fèi)的空間遠(yuǎn)遠(yuǎn)小于啟動(dòng)一個(gè)進(jìn)程所花費(fèi)的空間,,而且,,線程間彼此切換所需的時(shí)間也遠(yuǎn)遠(yuǎn)小于進(jìn)程間切換所需要的時(shí)間。/ v9 C5 Z& U) t8 c5 i
線程間方便的通信機(jī)制,。對不同進(jìn)程來說,,它們具有獨(dú)立的數(shù)據(jù)空間,要進(jìn)行數(shù)據(jù)的傳遞只能通過通信的方式進(jìn)行,,這種方式不僅費(fèi)時(shí),,而且很不方便。線程則不然,,由于同一進(jìn)程下的線程之間共享數(shù)據(jù)空間,,所以一個(gè)線程的數(shù)據(jù)可以直接為其它線程所用,這不僅快捷,,而且方便,。5 i! b4 C& k3 ]6 P) q+ B4 P3 H4 T
' x! X6 p. u2 L0 N
! b- p A5 R, L# @6 v. |. O
3、線程操作的函數(shù)
8 Z! V& z; X: M+ u: N+ Q" m% n#include <pthread.h> 3 |+ p6 x6 r) J+ w5 H( P( U
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
2 o1 H6 w5 @, Y/ d) Rint pthread_join (pthread_t tid, void ** status); 6 _4 N: f; v( E
pthread_t pthread_self (void); 6 L: q9 X" h8 Y8 c
int pthread_detach (pthread_t tid); : l' f4 p7 V2 D+ ^
void pthread_exit (void *status);
+ r/ Y, b! E) p* N3 f& Q, a" e: a
! o. i" |( i) Z: r5 n3 Mpthread_create:用于創(chuàng)建一個(gè)線程,,成功返回0,,否則返回Exxx(為正數(shù))。) o {# n( _5 S# D" }/ ~
pthread_t *tid:線程id的類型為pthread_t,,通常為無符號整型,,當(dāng)調(diào)用pthread_create成功時(shí),通過*tid指針返回,。% X* U6 u! [6 \$ `( u
3 q" L* j# R, V/ ?
const pthread_attr_t *attr:指定創(chuàng)建線程的屬性,,如線程優(yōu)先級、初始棧大小,、是否為守護(hù)進(jìn)程等,。可以使用NULL來使用默認(rèn)值,,通常情況下我們都是使用默認(rèn)值,。* l. h( g+ s) H# M% e @) ]
! J$ Y i) R$ C) s& p$ H/ T
void *(*func) (void *):函數(shù)指針func,指定當(dāng)新的線程創(chuàng)建之后,將執(zhí)行的函數(shù),。& g6 H& S+ K3 ]- h6 \
9 s; F l, {( k8 B2 rvoid *arg:線程將執(zhí)行的函數(shù)的參數(shù),。嵌入式系統(tǒng)學(xué)習(xí)意義氣嗚嗚吧久零就易,如果想傳遞多個(gè)參數(shù),,請將它們封裝在一個(gè)結(jié)構(gòu)體中,。
" a( z, Y9 L: k6 k0 `6 D2 r' Z! T% k
pthread_join:用于等待某個(gè)線程退出,成功返回0,,否則返回Exxx(為正數(shù)),。. k2 A" e2 k: @7 Q; _9 x6 O3 N
pthread_t tid:指定要等待的線程ID4 @" D) _# |/ ~( ?% ^ q
" z4 ^5 y# R; s6 y& S
void ** status:如果不為NULL,,那么線程的返回值存儲(chǔ)在status指向的空間中(這就是為什么status是二級指針的原因,!這種才參數(shù)也稱為“值-結(jié)果”參數(shù))。9 ~; E0 s, E. L0 X
0 n1 j# U \( o% z7 Y. c/ I& o6 o
pthread_self:用于返回當(dāng)前線程的ID,。& `: [! o4 Q) f3 ^( k! t* z
pthread_detach:用于是指定線程變?yōu)榉蛛x狀態(tài),,就像進(jìn)程脫離終端而變?yōu)楹笈_進(jìn)程類似。成功返回0,,否則返回Exxx(為正數(shù)),。變?yōu)榉蛛x狀態(tài)的線程,如果線程退出,,它的所有資源將全部釋放,。而如果不是分離狀態(tài),線程必須保留它的線程ID,,退出狀態(tài)直到其它線程對它調(diào)用了pthread_join,。$ I* i8 i9 [; f* I/ I; L
pthread_exit用于終止線程,可以指定返回值,,以便其他線程通過pthread_join函數(shù)獲取該線程的返回值,。
* q# y$ J& l( b8 Q8 C. Q* m* Q# Ivoid *status:指針線程終止的返回值。
1 Y+ V8 ^4 s8 ~/ _6 I2 J' T8 S
- s+ s& v$ \+ b/ j4,、線程間互斥* S6 o4 m3 ~ |+ f9 z
使用互斥鎖(互斥)可以使線程按順序執(zhí)行,。通常,互斥鎖通過確保一次只有一個(gè)線程執(zhí)行代碼的臨界段來同步多個(gè)線程,�,;コ怄i還可以保護(hù)單線程代碼。' ~. s0 r& y4 c- i- ?7 f
int pthread_mutex_lock(pthread_mutex_t * mptr); i0 j# L( F4 `, A1 \$ G! g
int pthread_mutex_unlock(pthread_mutex_t * mptr);6 o* I# c7 ]& K- d( ]. q0 p$ A3 q' N
4 u! a; }( w8 }
先聲明一個(gè)pthread_mutex_t類型的變量,,用作下面兩個(gè)函數(shù)的參數(shù),。在對臨界資源進(jìn)行操作之前需要pthread_mutex_lock先加鎖,操作完之后pthread_mutex_unlock再解鎖,。0 m# K- F; R# I& o# c, `
( ^: ~: G3 H6 i3 G2 |& d
! ~' t7 q3 V: U2 y2 s: U: C7 D5,、線程間同步; B! k. G, t) y y# ]; } i- n; {
條件變量:使用條件變量可以以原子方式阻塞線程,直到某個(gè)特定條件為真為止。條件變量始終與互斥鎖一起使用,。對條件的測試是在互斥鎖(互斥)的保護(hù)下進(jìn)行的,。
( O0 D, \# s+ y% r#include <pthread.h>
. D0 U0 H9 a2 O1 v7 e( gint pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr); / k' W/ |4 f5 V% M: O: G) q1 K
int pthread_cond_signal(pthread_cond_t *cptr); & c- u$ g7 V( i) C9 J. P
//Both return: 0 if OK, positive Exxx value on error
: b M! K2 y c0 H' f- }3 s# ]
% L& _: s# j+ ^; W5 X2 I7 _pthread_cond_wait用于等待某個(gè)特定的條件為真,pthread_cond_signal用于通知阻塞的線程某個(gè)特定的條件為真了,。在調(diào)用者兩個(gè)函數(shù)之前需要聲明一個(gè)pthread_cond_t類型的變量,,用于這兩個(gè)函數(shù)的參數(shù)。7 V2 O" ]; \5 i7 q+ w. U: R
/*
) W; D$ U- f) q5 A! \是否熟悉POSIX多線程編程技術(shù),?如熟悉,,編寫程序完成如下功能: ; w% z8 H/ F+ X) W! b' j9 m
1)有一int型全局變量g_Flag初始值為0; ' x7 T$ v, p0 D
2)在主線稱中起動(dòng)線程1,,打印“this is thread1”,,并將g_Flag設(shè)置為1
j5 n( I0 q3 G3 X/ J. y; O$ ] 3)在主線稱中啟動(dòng)線程2,打印“this is thread2”,,并將g_Flag設(shè)置為2
# w( d% @( p9 x% v, n8 _ 4)線程序1需要在線程2退出后才能退出 & b( n8 y( o% L* L3 y
5)主線程在檢測到g_Flag從1變?yōu)?,,或者從2變?yōu)?的時(shí)候退出
q/ W" d* ~: i |
|