在執行緒的同步化時,有些條件下執行緒必須等待,有些條件下則不用,這可以使用GCond來達到。
例如在生產者(Producer)與消費者(Consumer)的例子中,如果生產者會將產品交到倉庫,而消費者從倉庫取走產品,倉庫一次只能持有固定數量產品,如果生產者生產了過多的產品,倉庫叫生產者等一下
(wait),如倉庫中有空位放產品了再發信號(signal)通知生產者繼續生產,如果倉庫中沒有產品了,倉庫會告訴消費者等一下(wait),如果倉庫中有產品
了再發信號(signal)通知消費者來取走產品。
以下舉一個最簡單的:生產者每次生產一個int整數交至倉庫,而消費者從倉庫取走整數,倉庫一次只能持有一個整數,以程式實例來看:
#include <glib.h>
GMutex *mutex = NULL; GCond* cond = NULL; int storage = -1;
gboolean producer_thread_end = FALSE; gboolean consumer_thread_end = FALSE;
// 生產者透過此函式設定產品 void produce_product(int product) { g_mutex_trylock(mutex); if(storage != -1) { // 目前沒有空間收產品,請稍候! g_cond_wait(cond, mutex); }
storage = product; g_print("生產者設定 %d\n", storage);
// 喚醒消費者可以繼續工作了 g_cond_signal(cond); g_mutex_unlock(mutex); }
// 消費者透過此函式取走產品 int consume_product() { g_mutex_trylock(mutex); if(storage == -1) { // 缺貨了,請稍候! g_cond_wait(cond, mutex); }
int p = storage; g_print("消費者取走 %d\n", storage); storage = -1;
// 喚醒生產者可以繼續工作了 g_cond_signal(cond); g_mutex_unlock(mutex); return p; }
// 生產者執行緒會執行此函式 gpointer producer_thread(gpointer data) { int i; for(i = 1; i <= 10; i++) { g_usleep(rand()); produce_product(i); } producer_thread_end = TRUE; }
// 消費者執行緒會執行此函式 gpointer consumer_thread(gpointer data) { int i; for(i = 1; i <= 10; i++) { g_usleep(rand()); consume_product(); } consumer_thread_end = TRUE; }
gpointer checking_thread(gpointer mloop) { while(TRUE) { if(producer_thread_end && consumer_thread_end) { g_main_loop_quit(mloop); break; } g_usleep(1000); } }
int main(int argc, char *argv[]) { GMainLoop *mloop; if(!g_thread_supported()) { g_thread_init(NULL); } mloop = g_main_loop_new(NULL, FALSE);
mutex = g_mutex_new(); cond = g_cond_new();
g_thread_create(producer_thread, NULL, FALSE, NULL); g_thread_create(consumer_thread, NULL, FALSE, NULL); g_thread_create(checking_thread, mloop, FALSE, NULL); g_main_loop_run(mloop); return 0; }
執行結果:
生產者設定 1
消費者取走 1
生產者設定 2
消費者取走 2
生產者設定 3
消費者取走 3
生產者設定 4
消費者取走 4
生產者設定 5
消費者取走 5
生產者設定 6
消費者取走 6
生產者設定 7
消費者取走 7
生產者設定 8
消費者取走 8
生產者設定 9
消費者取走 9
生產者設定 10
消費者取走 10 |
生產者會生產10個整數,而消費者會消耗10個整數,由於倉庫只能放置一個整數,所以每生產一個就消耗一個,其結果如上所示是無誤的。
|
|