c++ - boost::wait 和 boost::condition 是否必须共享相同的互斥对象

标签 c++ multithreading boost c++11

boost::condition_variable cond;
boost::mutex mutex;

//thread #1
for(;;)
{
    D * d = nullptr;

    while( cb.pop(d) )  //cb is a circular buffer and manage is own mutex/lock internally
    {
        //...do something with d
    }
    boost::unique_lock<boost::_mutex> lock( mutex );
    cond.wait( mutex );
}

//thread #2
while(1)
{
    getchar();

    for( int i = 0 ; i < 1000 ; ++i )
    {
        cb.push(new D(i));      //one producer so no lock required

        cond.notify_one();     // no lock required here ?
    }
}

我想知道如果我的数据容器有自己的锁来避免数据竞争是否可以,另一方面 boost::wait 使用他的锁/互斥机制,正如 boost 文档所指定的那样?

否则,线程 1 是消费者,如果我只有一个线程“消费”,那么 wait 所需的锁似乎有点多余,不是吗?

编辑:我不关心丢失的更新。当我收到更新时,我用收到的数据更新一个对象。我只想要更新鲜的更新,而不是所有更新

最佳答案

你可以拥有任意数量的锁,但你会遇到竞争条件 除非 poppush 都受到与 waitnotify(并且锁在 决定等待和实际等待)。标准的成语是:

//  thread #1
// ...
{
    boost::unique_lock<boost::mutex> lock( mutex );
    while ( !cb.pop( d ) )
        cond.wait( mutex );
}
// process d


//  thread #2
// ...
{
    boost::unique_lock<boost::mutex> lock( mutex );
    cb.push( new D(i) );
    cond.notify_one();
}

尝试在线程 #1 中的 pop 上循环更复杂,至少 如果你想在 d 的处理过程中释放锁。你需要 像这样的东西:

boost::unique_lock<boost::mutex> lock( mutex );
while ( cb.pop( d ) ) {
    lock.unlock();
    //  process d
    lock.lock();
}
cond.wait( mutex );

它更复杂,我看不出你能从中得到什么。只是 使用已知的可靠工作的常用模式。

FWIW:您的代码充满了竞争条件:对于初学者:pop 线程 1 失败,有一个上下文切换,线程 2 执行 pushnotify,然后返回到执行 cond.wait 的线程 1。 等待,尽管队列中有东西。

我可能会补充说,几乎没有任何理由支持像这样的类型 循环缓冲区来管理自己的互斥锁。粒度是 太低。异常(exception)情况是弹出指令实际上等到 那里有东西,即(基于 std::deque):

T* CircularBuffer::push( std::auto_ptr<T> in )
{
    boost::unique_lock<boost::mutex> l( myMutex );
    myQueue.push_back( in.get() );
    in.release();  // Only after the push_back has succeeded!
    myCondition.notify_all();
}

std::auto_ptr<T> CircularBuffer::pop()
{
    boost::unique_lock<boost::mutex> l( myMutex );
    while ( myQueue.empty() ) {
        myCondition.wait();
    }
    std::auto_ptr<T> result( myQueue.front() );
    myQueue.pop_front();
    return result;
}

(注意接口(interface)中auto_ptr的使用。一旦提供者有 将对象传入队列,它不再有访问权限 它。)

关于c++ - boost::wait 和 boost::condition 是否必须共享相同的互斥对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6923641/

相关文章:

linux - Linux 上的线程利用率分析

c++ - 为什么用 Spirit 解析一个空行会在 map 中产生一个空的键值对?

c++ - 更改 CListCtrl 中特定项目的颜色?

c++ - 跨平台 SIMD 调用可能只用一个可执行文件吗?

C++ Directx 11 渲染问题

c++ - 使用 boost 解析嵌套的 xml

templates - C++模板静态整数常量: out of class definition

c++ - 用3D+2D图形重绘QGLWidget

java - java线程死锁

c# - worker线程加入BindingList时跨线程操作异常