这个g_cond_wait()的示例代码是否会导致未定义的行为?

时间:2015-06-16 11:39:11

标签: c multithreading glib

这是来自g_cond_wait()的Glib文档的示例:

gpointer current_data = NULL;
GMutex data_mutex;
GCond data_cond;

void push_data (gpointer data)
{
  g_mutex_lock (&data_mutex); // (3)
  current_data = data;
  g_cond_signal (&data_cond);
  g_mutex_unlock (&data_mutex); // (4)
}

gpointer pop_data (void)
{
  gpointer data;

  g_mutex_lock (&data_mutex); // (1)
  while (!current_data)
    g_cond_wait (&data_cond, &data_mutex); // (2)
  data = current_data;
  current_data = NULL;
  g_mutex_unlock (&data_mutex); // (5)

  return data;
}

现在让我们来看看:

  • 第一个线程调用pop_data()data_mutex被锁定(1)
  • g_cond_wait()被调用,data_mutex被解锁(2),第一个线程正在等待
  • 第二个线程调用push_data()data_mutex被锁定(3)
  • 第二个线程表示满足等待条件的第一个线程,解锁data_mutex(4)
  • 第一个线程醒来,退出g_cond_wait()并再次解锁data_mutex(5)

文档说解锁未锁定的互斥锁是未定义的。这是否意味着该示例包含错误?或者g_cond_wait()会在退出之前锁定互斥锁吗?

2 个答案:

答案 0 :(得分:4)

  

文档说解锁未锁定的互斥锁是未定义的。做这个   意味着该示例包含一个错误?或者g_cond_wait()会锁定互斥锁   在退出之前?

这里没有错误。没有解锁未在代码中锁定的互斥锁。 g_cond_wait()会在返回时锁定互斥锁。

Thread1调用g_cond_wait()并锁定互斥锁,g_cond_wait()以原子方式解锁互斥锁并等待该条件。在此之后,thread2锁定互斥锁并执行操作,然后信号发送到正在g_cond_wait()中等待的thread1。但是,由于互斥锁仍然不可用(thread2尚未解锁),因此thread1无法继续。因此,在thread2中的g_mutex_unlock()调用解锁后,thread1中的g_cond_wait()会锁定互斥锁并返回调用。

答案 1 :(得分:2)

是的,等待后,互斥锁再次被锁定。来自g_cond_wait()的glib文档:

  

当此函数返回时,mutex再次被锁定并由   调用线程。