執行緒間的通訊主要解決同步和互斥的問題
執行緒的同步是指某乙個執行緒必須等待另乙個執行緒的訊號才能進行相應的操作。執行緒的互斥則是指多個執行緒對同一資源進行操作時,應該保證在某乙個執行緒在操作時,其他執行緒不能操作該資源。
執行緒間的通訊可通過互斥鎖(mutex),訊號量(semphore),條件變數( condition variable) ,讀寫鎖(reader-writer lock)
互斥鎖是乙個變數,它有lock和unlock兩個狀態。互斥鎖一般被設定成全域性變數。開啟的互斥鎖可以由某個執行緒獲得。一旦獲得,這個互斥鎖會鎖再上。此後,只有該執行緒有權開啟。其他想要獲得互斥鎖的執行緒,要等到互斥鎖再次開啟的時候。
#### 互斥鎖的應用
/*多執行緒處理視窗售票,使用互斥量進行同步*/
#include
#inelude
#include
#include
#include
pthread_mutex_ t mutex_ x= pthread mutex_ initializer ;
int total_ticket_ num=20;
void
*sell_ticket
(void
*arg)
pthread_mutex_ unlock (
&mutex_x)
;//解鎖
}return0;
}int
main()
}sleep(30
);void
*retval ;
for(i=
0; i<
4; i++
)printf(」 retval =%ld\n 」 ,(long
*)retval);}
return0;
}
互斥量是執行緒必需的工具,但並不是萬能的。當執行緒正在等待共享資料內某個條件出現,他可能重複對互斥物件鎖定和解鎖,每次都會檢查共享資料結構,以查詢某個值。這樣會浪費時間和資源,頻繁查詢的效率也非常低。
條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補互斥鎖的不足。它常和互斥鎖一起使用。使用時,條件變數被用來阻塞乙個執行緒,當條件不滿足時,執行緒往往解開相應的互斥鎖並等待條件發生變化。一旦其他的某個執行緒改變了條件變數,他將通知相應的條件變數喚醒乙個或多個正被此條件變數阻塞的執行緒,這些執行緒將重新鎖定互斥鎖並重新測試條件是否滿足。
條件變數的應用#include
#include
using namespace std;
pthread_cond_t qready = pthread_cond_initializer ;
//初始構造條件變數
pthread_mutex_t qlock = pthread_mutex_initializer;
// 初始構造鎖
int x =10;
int y =20;
void
*funcl
(void
*arg)
void
*func2
(void
*arg)
cout << 」 func2 end」<}int
main
(int argc,
char
**ar**)
sleep(2
);iret =
pthread_create
(&tid2,
null
,func2,
null);
if(iret)
sleep(5
);return0;
}
在一些程式中存在讀寫者的問題。即對某些資源的訪問存在兩種可能的情況,一種是訪問必須是排他性的,即獨佔,這稱為寫操作;另一種情況就是訪問方式可以共享,即有多個執行緒同時訪問這個資源,這稱為讀操作。
(1)讀寫鎖比互斥鎖具有更高的適用性與並行性,可以有多個執行緒同時占用讀模式的讀寫鎖,但是只能有乙個執行緒占用寫模式的讀寫鎖。讀寫鎖有以下三種狀態:
1) 當讀寫鎖是寫加鎖狀態時,在這個鎖被解鎖之前,所有試圖對這個鎖枷鎖的執行緒都會被阻塞。
2) 當讀寫鎖是在讀加鎖狀態時,在這個鎖被解鎖之前,所有試圖以讀模式對這個鎖加鎖的執行緒都可以得到訪問權,但以寫模式對他進行加鎖的執行緒都會被阻塞。
3) 當讀寫鎖在讀模式的鎖狀態時,如果有另外的執行緒試圖以寫模式加鎖,讀寫鎖通常會阻塞隨後的讀模式鎖的請求,這樣可以避免讀模式長期占用,而等待的寫模式則長期阻塞。
讀寫鎖的使用#include
#include
#include
#include
#define threadnum 5
pthread_ rwlock_ t rwlock ;
void
*readers
(void
*arg)
void
*writers
(void
*arg)
int main (int argc,
char
**ar**)
pthread_attr_init
(&attr)
;/*pthread_attr_setdetachstate 用來設定執行緒的分離狀態,也就是說乙個執行緒怎麼樣終止自己,狀態設定為 pthread_create_detached , 表示以分離狀態啟動執行緒*/
pthread_attr_setdetachstate
(&attr , pthread_create_detached)
;for
( i =
0; i < threadnum ; i++
)else
sleep(5
);/*sleep 是為了等待另外的執行緒的執行*/
}return0;
}
執行緒還可以通過訊號量來實現通訊。訊號量和互斥鎖的區別:互斥鎖只允許乙個執行緒進入臨界區,而訊號量允許多個執行緒同時進入臨界區。
訊號量的應用
#include
#include,
#include
#include
#include
#define customer num 1 0
/* @scene : 某行業營業廳同時只能服務兩個顧客 。有多個顧客到來,顧客如果發現服務視窗已滿 , 就等待 ,如果有可用的服務窗 口 ,就接受服務。 * /
/* 將訊號量定義為全域性變數,方便多個執行緒共享*/
sem_ t sem ;
/* 每個執行緒要執行的例程 */
void
*get_service
(void
*thread id )
intmain
(int argc,
char
*ar**)
else
usleep (10)
;}/*等待所有顧客的執行緒結束*/
/*注意:這地方不能再用 i 做迴圈變數 , 因為可能執行緒正在訪問 i 的值*/
int j;
for( j =
0; j < customer_num ; j ++
)/*銷毀訊號量*/
sem_destroy (
&sem)
;return0;
}
多執行緒 執行緒間通訊
wait 方法的作用是使當前執行的執行緒進入等待,執行到 wait 一行進入等待 當執行緒被喚醒時從 wait 下一行開始執行。wait 方法需要在 synchronized 塊中呼叫,否則會報錯。wait 方法會釋放鎖,其它執行緒可以競爭獲得鎖 wait 方法有乙個帶時間引數的,當時間到了可以自動...
多執行緒 執行緒間通訊
學習思路 執行緒同步 鎖 wait notify join threadlocal 通過管道輸入 輸出流 字元流 位元組流 服務如果一直處於單執行緒訪問,那將毫無意義,多使用者訪問必然產生多執行緒,而多執行緒訪問必然離不開執行緒間通訊 多執行緒操作共享資源時勢必會產生執行緒安全的問題 也就是我們說的...
多執行緒間的通訊
多執行緒間的通訊 多個執行緒都在處理同乙個資源,但是處理的任務不一樣 等待喚醒機制。生產者,消費者 需求 生產者每生產乙個產品,消費者就消費乙個。通過同步,解決了沒生產就消費的問題。但是出現了連續的生產沒有消費的情況,和需求生產乙個,消費乙個的情況不符 使用了等待喚醒機制.wait 該方法可以讓執行...