Posted on 2012-12-14 11:46
鑫龍 閱讀(498)
評論(0) 編輯 收藏 引用 所屬分類:
linux編程
1 什么時候需要同步?
2 在linux中, 線程同步機制有哪些?各適用在怎樣的條件?進程同步有哪些?對應(yīng)的數(shù)據(jù)類型、API 各有哪些?
在當(dāng)前的POSIX標(biāo)準(zhǔn)中有三種線程同步機制,它們分別是:互斥量、讀寫鎖、條件變量。
關(guān)于進程同步機制,POSIX定義了一種信號燈,而system V 定義了另外一種信號燈。
----------------------------------------------------------------------
線程同步
(1)、互斥量(mutex)
互斥量本質(zhì)上是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成后釋放互斥量上的鎖。
對互斥量進行加鎖以后,任何其它試圖再次對互斥量加鎖的線程將會被阻塞直到當(dāng)前線程釋放該互斥鎖。如果釋放互斥鎖時有多個線程阻塞,所有在該互斥鎖上的阻塞線程都會變成可運行狀態(tài),第一個變?yōu)檫\行狀態(tài)的線程可以對互斥量加鎖,其它線程將會看到互斥鎖依然被鎖住,只能回去再次等待它重新變?yōu)榭捎谩T谶@種情況下,每次只有一個線程可以向前執(zhí)行。
pthread_mutex_t
pthread_mutex_init();
pthread_mutex_lock();
pthread_mutex_unlock();
pthread_mutex_destroy();
(2)
、讀寫鎖 讀寫鎖與互斥量類似,不過讀寫鎖允許更高的并行性?;コ饬恳词擎i住狀態(tài)要么是不加鎖狀態(tài),而且一次只有一個線程可以對其加鎖。
讀寫鎖可以由三種狀態(tài):讀模式下加鎖狀態(tài)、寫模式下加鎖狀態(tài)、不加鎖狀態(tài)。一次只有一個線程可以占有寫模式的讀寫鎖,但是多個線程可以同時占有讀模式的讀寫鎖。
在讀寫鎖是寫加鎖狀態(tài)時,在這個鎖被解鎖之前,所有試圖對這個鎖加鎖的線程都會被阻塞。當(dāng)讀寫鎖在讀加鎖狀態(tài)時,所有試圖以讀模式對它進行加鎖的線程都可以得到訪問權(quán),但是如果線程希望以寫模式對此鎖進行加鎖,它必須阻塞直到所有的線程釋放讀鎖。雖然讀寫鎖的實現(xiàn)各不相同,但當(dāng)讀寫鎖處于讀模式鎖住狀態(tài)時,如果有另外的線程試圖以寫模式加鎖,讀寫鎖通常會阻塞隨后的讀模式鎖請求。這樣可以避免讀模式鎖長期占用,而等待的寫模式鎖請求一直得不到滿足。
讀寫鎖非常適合于對數(shù)據(jù)結(jié)構(gòu)讀的次數(shù)遠(yuǎn)大于寫的情況。當(dāng)讀寫鎖在寫模式下時,它所保護的數(shù)據(jù)結(jié)構(gòu)就可以被安全地修改,因為當(dāng)前只有一個線程可以在寫模式下?lián)碛羞@個鎖。當(dāng)讀寫鎖在讀狀態(tài)下時,只要線程獲取了讀模式下的讀寫鎖,該鎖所保護的數(shù)據(jù)結(jié)構(gòu)可以被多個獲得讀模式鎖的線程讀取。
讀寫鎖也叫做共享-獨占鎖,當(dāng)讀寫鎖以讀模式鎖住時,它是以共享模式鎖住的;當(dāng)他以寫模式鎖住時,它是以獨占模式鎖住的。
pthread_rwlock_t
pthread_rwlock_init();
pthread_rwlock_rdlock();
pthread_rwlock_wrlock();
pthread_rwlock_unlock();
pthread_rwlock_destroy();
(3)
、條件變量(condition)和監(jiān)視器(monitor) 條件變量與互斥量一起使用時,允許線程以無競爭的方式等待特定的條件發(fā)生。
條件本身是由互斥量保護的。線程在改變條件狀態(tài)前必須首先鎖住互斥量,其它線程在獲得互斥量之前不會察覺到這種改變,因此必須鎖定互斥量以后才能計算條件。
pthread_cond_t
pthread_cond_init();
pthreadf_cond_wait();
pthread_cond_signal();
pthread_cond_destroy();
----------------------------------------------------------------------進程同步 信號量(Semaphore),有時被稱為信號燈,是在多線程環(huán)境下使用的一種設(shè)施,是可以用來保證兩個或多個關(guān)鍵代碼段不被并發(fā)調(diào)用。在進入一個關(guān)鍵代碼段之前,線程必須獲取一個信號量;一旦該關(guān)鍵代碼段完成了,那么該線程必須釋放信號量。其它想進入該關(guān)鍵代碼段的線程必須等待直到第一個線程釋放信號量。為了完成這個過程,需要創(chuàng)建一個信號量VI,然后將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個關(guān)鍵代碼段的首末端。確認(rèn)這些信號量VI引用的是初始創(chuàng)建的信號量。
POSIX信號燈:
sem_t
sem_open();
sem_init();
sem_wait();
sem_post();
sem_close();
sem_unlink();
SysV信號燈:
semget();
semop();
semctl();
3 線程同步機制和進程同步機制有什么區(qū)別?哪個使用的范圍更大?
顯然進程同步機制可以用于線程同步,而線程同步機制不能用于進程同步。