结构
GLibCond
描述 [src]
struct GCond {
/* No available fields */
}
GCond
结构是一个不透明数据结构,表示一个条件。如果线程发现某个条件为假,它们可以在 GCond
上阻塞。如果其他线程改变此条件的状态,它们将发出 GCond
信号,并导致等待线程被唤醒。
考虑以下共享变量示例。一个或多个线程可以等待将数据发布到变量,当另一个线程发布数据时,它可以发出信号唤醒等待线程之一以收集数据。
这是一个使用 GCond 阻塞线程直至满足条件的示例
gpointer current_data = NULL;
GMutex data_mutex;
GCond data_cond;
void
push_data (gpointer data)
{
g_mutex_lock (&data_mutex);
current_data = data;
g_cond_signal (&data_cond);
g_mutex_unlock (&data_mutex);
}
gpointer
pop_data (void)
{
gpointer data;
g_mutex_lock (&data_mutex);
while (!current_data)
g_cond_wait (&data_cond, &data_mutex);
data = current_data;
current_data = NULL;
g_mutex_unlock (&data_mutex);
return data;
}
现在,只要一个线程调用 pop_data()
,它将等待直至 current_data 为非 NULL
,即直到其他线程调用 push_data()。
该示例表明,条件变量的使用必须始终与互斥锁配对。如果没有使用互斥锁,则会在 while 循环检查 current_data
和 pop_data()
中的等待之间产生竞争。具体来说,另一个线程可以在检查后设置 current_data
,并在第一个线程进入睡眠之前发出 cond 信号(没有人等待它)。GCond
特别有用于以原子方式释放互斥锁并进入睡眠的能力。
仅在循环内部使用 g_cond_wait()
和 g_cond_wait_until()
函数来检查条件是否为真也非常重要。有关即使在返回后条件可能仍为假的原因的说明,请参阅 g_cond_wait()
。
如果 GCond
在静态存储空间中分配,则可以在没有初始化的情况下使用它。否则,您应该在 g_cond_init()
中调用它,并在完成后调用 g_cond_clear()
。
仅应通过 g_cond_ 函数访问 GCond
。
实例方法
g_cond_broadcast
如果线程正在等待 cond
,则所有这些线程将被解锁。如果没有线程正在等待 cond
,则此函数将不起作用。虽然不要求这样做,但最好在调用此函数时锁定与等待线程相同的互斥锁。
g_cond_signal
如果线程正在等待 cond
,则会解除至少一个线程的阻塞状态。如果没有线程正在等待 cond
,则此函数没有任何作用。在调用此函数时使用与等待线程相同的锁定是一种良好做法,但不是必需的。
g_cond_timed_wait
一直等待,直到此线程在 cond
上被唤醒,但不得超过 abs_time
指定的时间。在进入休眠状态之前会解锁 mutex
,并且在恢复之前会再次锁定。
已弃用:2.32