很顯然,pthread中的條件變量與Java中的wait,notify類似
假設有共享的資源sum,與之相關聯的mutex 是lock_s.假設每個線程對sum的操作很簡單的,與sum的狀態無關,比如只是sum++.那么只用mutex足夠了.程序員只要確保每個線程操作前,取得lock,然后sum++,再unlock即可.每個線程的代碼將像這樣add()
{
pthread_mutex_lock(lock_s);
sum++;
pthread_mutex_unlock(lock_s);
}
如果操作比較復雜,假設線程t0,t1,t2的操作是sum++,而線程t3則是在sum到達100的時候,打印出一條信息,并對sum清零.這種情況下,如果只用mutex, 則t3需要一個循環,每個循環里先取得lock_s,然后檢查sum的狀態,如果sum>=100,則打印并清零,然后unlock.如果sum<100,則unlock,并sleep()本線程合適的一段時間.
這個時候,t0,t1,t2的代碼不變,t3的代碼如下
print()
{
while (1)
{
pthread_mutex_lock(lock_s);
if(sum<100)
{
printf(“sum reach 100!”);
pthread_mutex_unlock(lock_s);
}
else
{
pthread_mutex_unlock(lock_s);
my_thread_sleep(100);
return OK;
}
}
}
這種辦法有兩個問題
1) sum在大多數情況下不會到達100,那么對t3的代碼來說,大多數情況下,走的是else分支,只是lock和unlock,然后sleep().這浪費了CPU處理時間.
2) 為了節省CPU處理時間,t3會在探測到sum沒到達100的時候sleep()一段時間.這樣卻又帶來另外一個問題,亦即t3響應速度下降.可能在sum到達200的時候,t3才會醒過來.
3) 這樣,程序員在設置sleep()時間的時候陷入兩難境地,設置得太短了節省不了資源,太長了又降低響應速度.真是難辦啊!
這個時候,condition variable內褲外穿,從天而降,拯救了焦頭爛額的你.
你首先定義一個condition variable.
pthread_cond_t cond_sum_ready=PTHREAD_COND_INITIALIZER;
t0,t1,t2的代碼只要后面加兩行,像這樣
add()
{
pthread_mutex_lock(lock_s);
sum++;
pthread_mutex_unlock(lock_s);
if(sum>=100)
pthread_cond_signal(&cond_sum_ready);
}
而t3的代碼則是
print
{
pthread_mutex_lock(lock_s);
while(sum<100)
pthread_cond_wait(&cond_sum_ready, &lock_s);
printf(“sum is over 100!”);
sum=0;
pthread_mutex_unlock(lock_s);
return OK;
}
注意兩點:
1) 在thread_cond_wait()之前,必須先lock相關聯的mutex, 因為假如目標條件未滿足,pthread_cond_wait()實際上會unlock該mutex, 然后block,在目標條件滿足后再重新lock該mutex, 然后返回.
2) 為什么是while(sum<100),而不是if(sum<100) ?這是因為在pthread_cond_signal()和pthread_cond_wait()返回之間,有時間差,假設在這個時間差內,還有另外一個線程t4又把sum減少到100以下了,那么t3在pthread_cond_wait()返回之后,顯然應該再檢查一遍sum的大小.這就是用while的用意
boost lib
http://www.stlchina.org/twiki/bin/view.pl/Main/BoostThread#safag7ZYn7rqw
文章出處:DIY部落(http://www.diybl.com/course/3_program/c++/cppxl/20090508/166837.html)
posted on 2009-07-05 01:07
Frank_Fang 閱讀(9240)
評論(2) 編輯 收藏 所屬分類:
Linux | ACE網絡編程