【问题标题】:Difference between Boost and Pthread condition variablesBoost 和 Pthread 条件变量之间的区别
【发布时间】:2013-05-03 06:50:51
【问题描述】:

我发现了一些使用 boost 线程、互斥锁和条件变量的代码,但我想尝试用 posix 线程重写这段代码。

这是 Boost 代码,我找到了here

void push(Data const& data)
{
    boost::mutex::scoped_lock lock(the_mutex);
    the_queue.push(data);
    lock.unlock();
    the_condition_variable.notify_one();
}

在我使用 pthreads 的代码中,我不确定是否以正确的方式使用条件变量,因为我不确定 notify_one() 和标记变量是否相同:

void push(T const& data)
{
    pthread_mutex_lock(&m_mutex);
    m_queue.push(data);
    pthread_mutex_unlock(&m_mutex);
    pthread_cond_signal(&m_condition);
}

初始化是在这样之前完成的:

pthread_mutex_t m_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t m_condition = PTHREAD_COND_INITIALIZER;

另一方面,他们正在使用the_condition_variable.wait(lock); ...这一行我会用这样的pthreads重写:pthread_cond_wait( &m_condition, &m_mutex);

我走对了吗?

【问题讨论】:

  • 一个是带有C++接口的C++类,另一个是带有C风格接口的C风格结构? Boost 实现很可能在幕后使用 pthread 接口进行实现。
  • 嗯,所以我应该始终解锁互斥锁,因为没有实例(如在 boost 实现中)在离开推送功能或任何其他功能时会被破坏,对吧?

标签: c++ boost pthreads mutex boost-thread


【解决方案1】:

Boost 线程原语的语义基于 pthread,所以在那个级别应该没有区别。 然而,Boost 将它们包装在一个基于 C++ 类的接口中,并且在 特别是,隐式支持 RAII 用于锁定 互斥体;如果你想直接使用pthread,你肯定会 例如,想要实现自己的范围锁变体。 就目前而言,您对push 的实现未能释放 如果m_queue.push( data ) 抛出(它可以抛出),则锁定。

此外,您应该释放锁之前发出信号。 (这是 Boost 代码和 pthread 代码中的错误。)和 避免您引用的网站中的代码:它完全坏了, 而且根本不是线程安全的。

编辑:

经过更多调查:我看到你引用的网站是 由享有非常很高声誉的 Anthony Williams 撰写 关于线程问题。在页面底部,他 有一个正确的“最终代码”版本,在每个 细节。尽管对我来说似乎不清楚,但在阅读 页面,我认为所有之前的版本(包括 您正在复制的)作为“初稿”给出,并且已知 在某些细节上是不正确的。 (我还是觉得他应该 让这更清楚。有一些极其危险的做法 在他的第一个示例中:例如返回引用。)

【讨论】:

  • 谢谢,我阅读了我引用的文章的 cmets,他们提到这不是一个好的解决方案。我想出了一个新的解决方案:pastebin.com/sBZqBtmZ ...这样更好吗?
  • 没有。它充满了竞争条件,如果出现异常也将无法解锁互斥锁。正确的解决方案必须 1) 使用 RAII 来确保释放互斥锁,无论如何,2) 在每个函数的顶部锁定,在底部释放,只有等待中隐含的干预解锁,以及 3) 循环等待,测试条件。它应该使用pthread_cond_t,而不是sem_t,因为只有pthread_cond_t 才能正确处理互斥锁的解锁和锁定。
  • 我的第一个方法看起来像这样:pastebin.com/FSCFWQMD ...但我不知道如何在调用空后解锁互斥锁。我是否也应该像 boost 家伙一样创建一个 Lock-Class?
  • 首先,调用empty后没有解锁互斥锁;当您调用pthread_cond_wait 时,该互斥锁必须保持不变。对于其余部分,您绝对应该创建一个锁类,它将互斥锁锁定在其构造函数中,并在析构函数中解锁它。定义 this 的一个实例应该是你所有函数的第一行(否则你永远不需要显式解锁互斥锁)。
  • 非常感谢!我会将其设置为答案,但如果看起来更好,请告诉我:pastebin.com/VJAKKmPe
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多