在執行緒的同步化時,有些條件下執行緒必須等待,有些條件下則不用,這可以使用GCond來達到。
例如在生產者(Producer)與消費者(Consumer)的例子中,如果生產者會將產品交到倉庫,而消費者從倉庫取走產品,倉庫一次只能持有固定數量產品,如果生產者生產了過多的產品,倉庫叫生產者等一下 (wait),如倉庫中有空位放產品了再發信號(signal)通知生產者繼續生產,如果倉庫中沒有產品了,倉庫會告訴消費者等一下(wait),如果倉庫中有產品 了再發信號(signal)通知消費者來取走產品。
以下舉一個最簡單的:生產者每次生產一個int整數交至倉庫,而消費者從倉庫取走整數,倉庫一次只能持有一個整數,以程式實例來看:
- gcond_demo.c
#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
      消費者取走 1
生產者設定 2
消費者取走 2
生產者設定 3
消費者取走 3
生產者設定 4
消費者取走 4
生產者設定 5
消費者取走 5
生產者設定 6
消費者取走 6
生產者設定 7
消費者取走 7
生產者設定 8
消費者取走 8
生產者設定 9
消費者取走 9
生產者設定 10
消費者取走 10
生產者會生產10個整數,而消費者會消耗10個整數,由於倉庫只能放置一個整數,所以每生產一個就消耗一個,其結果如上所示是無誤的。

