1

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

这是 Boost 代码,我在这里找到:

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);

我在正确的轨道上吗?

4

1 回答 1

1

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

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

编辑:

经过更多调查:我看到您引用的网站是由安东尼威廉姆斯创作的,他在线程问题方面享有很高的声誉在页面底部,他有一个“最终密码”版本,每一个细节都是正确的。尽管对我来说似乎并不清楚,但在阅读该页面时,我认为所有先前的版本(包括您从中复制的版本)都是作为“初稿”给出的,并且在某些细节上已知是不正确的。(我仍然认为他应该更清楚地说明这一点。在他的第一个示例中存在一些极其危险的做法:例如返回引用。)

于 2013-05-03T07:53:08.613 回答