【问题标题】:Will this example code for g_cond_wait() lead to undefined behaviour?g_cond_wait() 的这个示例代码会导致未定义的行为吗?
【发布时间】:2015-06-16 11:39:11
【问题描述】:

这是来自 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()会在退出前锁定互斥锁吗?

【问题讨论】:

    标签: c multithreading glib


    【解决方案1】:

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

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

    Thread1 调用 g_cond_wait() 并锁定互斥锁,g_cond_wait() 原子地解锁互斥锁并等待条件。之后,thread2 锁定互斥体并执行操作,然后向在g_cond_wait() 中等待的thread1 发送信号。但是 thread1 无法继续,因为互斥锁仍然不可用(thread2 尚未解锁)。所以在thread2中调用g_mutex_unlock()解锁后,在thread1中g_cond_wait()锁定互斥体,调用返回。

    【讨论】:

      【解决方案2】:

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

      当此函数返回时,互斥量再次被锁定并归 调用线程。

      【讨论】:

      • 文档说解锁非锁定互斥体是未定义的。这是否意味着示例包含错误?
      • @BlueMoon - 因为g_cond_wait 在返回时会锁定互斥锁,所以没有路径可以解锁未锁定的互斥锁。
      • @mtrw - 抱歉,不知道我在阅读文档时是怎么错过的。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-25
      • 2014-08-11
      • 2016-09-04
      • 2014-08-04
      • 1970-01-01
      • 2015-10-16
      • 2013-04-24
      相关资源
      最近更新 更多