久久久国产一区二区_国产精品av电影_日韩精品中文字幕一区二区三区_精品一区二区三区免费毛片爱
機(jī)械社區(qū)
標(biāo)題:
Linux多線程及線程間同步
[打印本頁]
作者:
tainqing
時(shí)間:
2017-12-8 17:15
標(biāo)題:
Linux多線程及線程間同步
1、
進(jìn)程和線程的區(qū)別
) v5 {, D. `1 t" P$ }8 Y
進(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)程所擁有的全部資源。
5 B$ ^5 [( j) z9 ]
3 }5 C3 t$ Z( X; M( M& \
地址空間:進(jìn)程有獨(dú)立的地址空間,包括文本區(qū)域(
text region)、數(shù)據(jù)區(qū)域(data region)和堆棧(stack region);一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響;線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑,線程有自己的堆棧和局部變量(在運(yùn)行中必不可少的資源),但線程之間沒有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉。同一進(jìn)程內(nèi)的線程共享進(jìn)程的地址空間。
, D/ x9 {5 \( U8 v! c5 a$ Y1 t. h
( R* O2 n3 n& c5 O2 {3 R! J1 Z
通信
:進(jìn)程間通信
IPC,線程間可以直接讀寫進(jìn)程數(shù)據(jù)段(如全局變量)來進(jìn)行通信——需要進(jìn)程同步和互斥手段的輔助,以保證數(shù)據(jù)的一致性。
: l4 g d, E9 k% t
9 o% k2 Z* m& C+ C7 q: V
調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多。
5 e/ t! G N" p5 X9 P T
4 {' Z9 s) g! R7 A$ Q) h u
在多線程
OS中,進(jìn)程不是一個(gè)可執(zhí)行的實(shí)體。
p, O+ M, @* Q1 v4 _4 {, H& A! P
& C" d9 U" N1 C% B1 R7 T, B
地址空間
:進(jìn)程內(nèi)的一個(gè)執(zhí)行單元;進(jìn)程至少有一個(gè)線程;它們共享進(jìn)程的地址空間;而進(jìn)程有自己獨(dú)立的地址空間;
; h; X# b1 ~8 S! m+ U5 g# Z6 X
. t1 v+ J7 k5 G; u3 B+ n; x
資源擁有
:進(jìn)程是資源分配和擁有的單位,同一個(gè)進(jìn)程內(nèi)的線程共享進(jìn)程的資源
& p9 C8 j9 V. w3 J* S
1 N0 Q, ~$ K% R* u
線程是處理器調(diào)度的基本單位
,但進(jìn)程不是.
+ ~. R! ^+ G0 }1 y7 S3 o
3 y7 G3 Q) Z3 ~ v V2 G( T. H, [
二者均可并發(fā)執(zhí)行
.
$ d% n" u. s7 a/ f) b0 @3 ^4 [
. J/ S# g( \0 r! T3 W3 c/ X- p
2、使用線程原因
/ v6 R0 [! w- U( }
在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í)間。
8 s' [1 v& d4 J5 E1 |) T9 E$ k
線程間方便的通信機(jī)制。對(duì)不同進(jìn)程來說,它們具有獨(dú)立的數(shù)據(jù)空間,要進(jìn)行數(shù)據(jù)的傳遞只能通過通信的方式進(jìn)行,這種方式不僅費(fèi)時(shí),而且很不方便。線程則不然,由于同一進(jìn)程下的線程之間共享數(shù)據(jù)空間,所以一個(gè)線程的數(shù)據(jù)可以直接為其它線程所用,這不僅快捷,而且方便。
" g& N- _( A: K) p( f
0 x3 k- _+ w- D8 h+ f
' L) J, u. k2 v# X3 k& n) y8 D
3、線程操作的函數(shù)
6 c7 n+ ?* I0 E% E3 D% I$ k
#include <pthread.h>
/ f) B8 K" p# w
int pthread_create(pthread_t *
ti
d, const pthread_attr_t *attr, void *(*func) (void *), void *arg);
: w; x5 e- m9 f. F7 w6 O% w
int pthread_join (pthread_t tid, void ** status);
$ O% o' {1 ~1 U+ e4 x4 B& }
pthread_t pthread_self (void);
8 b9 U: Z9 T. L
int pthread_detach (pthread_t tid);
, m9 [8 G. ~, x- ^
void pthread_exit (void *status);
6 _( B, m+ l2 K: M# o
: D- X1 j8 s* s6 ]' }
pthread_create:用于創(chuàng)建一個(gè)線程,成功返回0,否則返回Exxx(為正數(shù))。
& A, H. W# g/ O2 M- x$ G
pthread_t *tid:線程id的類型為pthread_t,通常為無符號(hào)整型,當(dāng)調(diào)用pthread_create成功時(shí),通過*tid指針返回。
4 u7 N1 _! S# p: Z; l1 u8 L) X0 r
8 [2 Z! b! T G0 E- c. O
const pthread_attr_t *attr:指定創(chuàng)建線程的屬性,如線程優(yōu)先級(jí)、初始棧大小、是否為守護(hù)進(jìn)程等。可以使用NULL來使用默認(rèn)值,通常情況下我們都是使用默認(rèn)值。
: c5 m, u( P# s* `: r
$ W* {" h- `- v* \4 L: E: {
void *(*func) (void *):函數(shù)指針func,指定當(dāng)新的線程創(chuàng)建之后,將執(zhí)行的函數(shù)。
8 N8 F, C, O6 V9 j) Y6 W% e1 q
& u# }" F7 G! L* S# a+ o. B
void *arg:線程將執(zhí)行的函數(shù)的參數(shù)。
嵌入式系統(tǒng)學(xué)習(xí)意義氣嗚嗚吧久零就易,
如果想傳遞多個(gè)參數(shù),請(qǐng)將它們
封裝
在一個(gè)結(jié)構(gòu)體中。
- R# L- Q. ^! Y/ u2 \1 D
6 {$ C/ b2 T8 `, Q& L
pthread_join:用于等待某個(gè)線程退出,成功返回0,否則返回Exxx(為正數(shù))。
9 x7 m9 G; I, m9 X- h
pthread_t tid:指定要等待的線程ID
7 S7 V7 ]4 _2 p( c2 ^
; ?+ G; h( d* R) G; u* A
void ** status:如果不為NULL,那么線程的返回值存儲(chǔ)在status指向的空間中(這就是為什么status是二級(jí)指針的原因!這種才參數(shù)也稱為“值-結(jié)果”參數(shù))。
# y' c; \, E( v% c& r' N2 }' _* S7 o
+ F' U: d3 D% D9 t' o$ ]
pthread_self:用于返回當(dāng)前線程的ID。
- J" _& @4 P+ C/ @ K
pthread_detach:用于是指定線程變?yōu)榉蛛x狀態(tài),就像進(jìn)程脫離終端而變?yōu)楹笈_(tái)進(jìn)程類似。成功返回0,否則返回Exxx(為正數(shù))。變?yōu)榉蛛x狀態(tài)的線程,如果線程退出,它的所有資源將全部釋放。而如果不是分離狀態(tài),線程必須保留它的線程ID,退出狀態(tài)直到其它線程對(duì)它調(diào)用了pthread_join。
5 O2 ]8 K; s6 W% l# y* b# g
pthread_exit用于終止線程,可以指定返回值,以便其他線程通過pthread_join函數(shù)獲取該線程的返回值。
0 m/ r" g6 I* N8 s' n
void *status:指針線程終止的返回值。
8 U+ K. n2 g; d) ~* G
. _9 p' a V' j8 T& r% M
4、線程間互斥
5 x R2 E8 ~& k+ N$ ^
使用互斥鎖(互斥)可以使線程按順序執(zhí)行。通常,互斥鎖通過確保一次只有一個(gè)線程執(zhí)行代碼的臨界段來同步多個(gè)線程。互斥鎖還可以保護(hù)單線程代碼。
6 s) h) K) o) `/ N q
int pthread_mutex_lock(pthread_mutex_t * mptr);
# a( K: N" a, ^, ~* X# @6 _
int pthread_mutex_unlock(pthread_mutex_t * mptr);
% @4 g. K2 m2 m, b+ b/ A: U
7 C+ `4 A0 A2 \! ~; Y! }
先聲明一個(gè)
pthread_mutex_t類型的變量,用作下面兩個(gè)函數(shù)的參數(shù)。在對(duì)臨界資源進(jìn)行操作之前需要pthread_mutex_lock先加鎖,操作完之后pthread_mutex_unlock再解鎖。
$ L% t: z, [' h) k
( z' g0 ~3 N) ^2 s# b" v
1 v; B0 |: i9 @! M# g x% ~
5、線程間同步
! {$ w+ I1 l* C
條件變量:使用條件變量可以以原子方式阻塞線程,直到某個(gè)特定條件為真為止。條件變量始終與互斥鎖一起使用。對(duì)條件的測(cè)試是在互斥鎖(互斥)的保護(hù)下進(jìn)行的。
5 I0 W! u- V0 C; _9 e5 W/ x- x
#include <pthread.h>
7 I3 k1 F9 K4 V }: s
int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);
; t* W6 ?8 S0 F( {' Q
int pthread_cond_signal(pthread_cond_t *cptr);
, I/ o9 c* u% S2 V
//Both return: 0 if OK, positive Exxx value on error
. Z5 H) g" X/ l) N, J6 H# A* P
( R8 Z3 q5 X( H! B8 J
pthread_cond_wait用于等待某個(gè)特定的條件為真,pthread_cond_signal用于通知阻塞的線程某個(gè)特定的條件為真了。在調(diào)用者兩個(gè)函數(shù)之前需要聲明一個(gè)pthread_cond_t類型的變量,用于這兩個(gè)函數(shù)的參數(shù)。
3 ~3 j, a) A0 B& M( m- A
/*
2 z7 s" ?' L: a: u7 b
是否熟悉
POSIX多線程編程技術(shù)?如熟悉,編寫程序完成如下功能:
! p* o3 Z) `8 q. X" Z
1)有一int型全局變量g_Flag初始值為0;
1 t: l! a6 U' h! j- G+ T9 z; ^( D
2)在主線稱中起動(dòng)線程1,打印“this is thread1”,并將g_Flag設(shè)置為1
9 d6 |5 l% t! T
3)在主線稱中啟動(dòng)線程2,打印“this is thread2”,并將g_Flag設(shè)置為2
9 I% t( n- ]# V
4)線程序1需要在線程2退出后才能退出
, h2 J1 w/ v% i9 b
5)主線程在檢測(cè)到g_Flag從1變?yōu)?,或者從2變?yōu)?的時(shí)候退出
) U: F; F0 L, o9 b- g: }
歡迎光臨 機(jī)械社區(qū) (http://www.ytsybjq.com/)
Powered by Discuz! X3.5