使用讀寫鎖、互斥鎖可以阻塞執行緒,使對臨界**的操作變為原子操作。其臨界區**只有兩種狀態,鎖定和非鎖定。而如果需要外部的條件判斷之後才執行某些臨界區**,比如經典的生產者-消費者模型,生產者和消費者對資源的使用時互斥的,但是消費者對資源的使用還有乙個前提就是資源不為空,但是這個判斷互斥鎖沒法實現。
因此需要使用條件變數,在消費者進入臨界區並被告知當前無可用資源的時候,阻塞消費者執行緒;當生產者生產了可供消費者使用的資源之後,提示消費者可以使用資源(喚醒阻塞的消費者執行緒)。比如下面的**:
鍊錶node *head=null
while(head)
//鍊錶不為空的處理**
條件變數不是鎖,但是條件變數可以阻塞執行緒。
使用條件變數和互斥鎖,其中:
互斥鎖:保護一段共享區域;
條件變數:引起阻塞。
下面是經典的生產者-消費者模型。
生產者和消費者模型:生產者生產商品,消費者消費商品,共享「商品」資源。
消費者:一直消費
//一直消費
while(1)
//吃燒餅
pthread_mutex_lock(&mutex);
sleep(1);
}生產者:
//一直生產
while(1)
條件不滿足時,阻塞執行緒;
條件滿足時,通知阻塞的執行緒開始工作。
//型別名 變數名
pthread_cond_t cond
(1) 初始化乙個條件變數
pthread_cond_init(
pthread_cond_t* restrict cond,//條件變數型別的變數
const pthread_condattr_t* restrict attr//引數,預設null
);
(2) 銷毀乙個條件變數
pthread_cond_destroy(pthread_cond_t* cond);
(3) 阻塞等待乙個條件變數
pthread_cond_wait(
pthread_cond_t* restrict cond, //條件變數型別的變數
pthread_mutex_t* restrict mutex//互斥鎖型別的變數
);
使用條件變數阻塞執行緒:傳入引數為條件變數型別的變數以及互斥鎖型別的變數;
使用條件變數阻塞執行緒時:將已經上鎖的mutex解鎖;
條件變數通知解除阻塞之後:加鎖,訪問共享資料。
(4) 限時等待乙個條件變數
pthread_cond_timedwait(
pthread_cond_t* restrict cond,
pthread_mutex_t* restrict mutex,
const struct timespec* restrict abstime
);
(5)喚醒至少乙個阻塞在條件變數上的執行緒
pthread_cond_signal(pthread_cond_t* cond);
(6)喚醒全部阻塞在條件變數上的執行緒
pthread_cond_broadcast(pthread_cond_t* cond);
//消費者,生產者模型
#include #include #include #include #include #include //建立節點的結構
typedef struct nodenode;
//定義乙個指標,指向鍊錶頭部
node* head=null;
//執行緒同步需要互斥鎖
pthread_mutex_t mutex;
//條件變數
pthread_cond_t cond;
//生產者
void* producer(void* arg)
return null;
}void* customer(void* arg)
//鍊錶不為空,刪除頭節點
node* pdel=head;
head=head->next;
printf("***** customer: %lu, %d\n",pthread_self(),pdel->data);
free(pdel);
//解鎖
pthread_mutex_unlock(&mutex); }
return null;
}int main(void)
執行緒同步 條件變數
當我們需要控制對記憶體資源的訪問的時候,可以用一種簡單的加鎖的方法來控制,即互斥鎖。但互斥鎖有乙個明顯的缺點,就是它只有兩個狀態 鎖定和非鎖定。而條件變數通過允許執行緒阻塞和等待另乙個執行緒傳送訊號的方法彌補來互斥鎖的不足。條件變數通常和互斥鎖一起使用。使用過程 1.呼叫pthread mutex ...
執行緒同步 條件變數
1.問題引入 互斥鎖問題,假設現在有兩個資源a和b,乙個執行緒先拿a再拿b,另乙個則相反,這樣導致的問題就是死鎖,即兩個執行緒無休止的互相等待 include include include include pthread mutex t g mtxa pthread mutex initializ...
執行緒同步 條件變數
多執行緒中條件變數的使用 執行緒同步之條件變數 include include include include include include include include using namespace std 乙個簡單的緩衝區類 struct buffer bool full return f...