正确使用 boost::wait boost::condition

发布于 2024-11-24 17:14:45 字数 597 浏览 1 评论 0原文

boost::condition cond;
boost::recursive_mutex mutex;

for(;;)
{
    D * d = nullptr;

    while( cb.pop(d) ) 
    {

    }

    boost::lock_guard<boost::recursive_mutex> lock( **mutex** );
    cond.wait( **mutex** );
}


while(1)
{
    getchar();

    for( int i = 0 ; i < 1000 ; ++i )
    {
        cb.push(new D(i));           
        boost::lock_guard<boost::recursive_mutex> lock( **mutex** );
        cond.notify_one();
    }
}

我的疑问是关于互斥体,我只需要互斥体对象?

编辑:

cb 是一个循环缓冲区。 我想实现一种生产者-消费者模式,

我是否必须对 wait 和 notify_one 使用相同的互斥体?

boost::condition cond;
boost::recursive_mutex mutex;

for(;;)
{
    D * d = nullptr;

    while( cb.pop(d) ) 
    {

    }

    boost::lock_guard<boost::recursive_mutex> lock( **mutex** );
    cond.wait( **mutex** );
}


while(1)
{
    getchar();

    for( int i = 0 ; i < 1000 ; ++i )
    {
        cb.push(new D(i));           
        boost::lock_guard<boost::recursive_mutex> lock( **mutex** );
        cond.notify_one();
    }
}

My doubt is about the mutex, I only need on mutex object ?

EDIT:

cb is a circular buffer.
I want to implement a sort of producer-consumer pattern

do I have to use the same mutex for wait and notify_one ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

魄砕の薆 2024-12-01 17:14:45

假设您使用的是最新版本的 boost,boost::conditionboost::condition_variable_any 相同,我相信它与 std 相同::condition_variable_any

如果所有这些都是正确的,或者至少近似正确,您的代码应该可以编译,但如果您调用 cond.wait(mutex) 并递归锁定 mutex ,则可能会死锁。

我建议:

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

// In one thread

for(;;)
{
    D * d = nullptr;

    boost::unique_lock<boost::mutex> lock( mutex );
    while( cb.pop(d) ) 
    {

    }
    while (cb.empty())
       cond.wait( lock );
}

// In another thread

while(1)
{
    getchar();

    for( int i = 0 ; i < 1000 ; ++i )
    {
        boost::lock_guard<boost::mutex> lock( mutex );
        cb.push(new D(i));           
        cond.notify_one();
    }
}

如果您的实现支持它,请将 std 替换为 boost。这:

  1. 不使用递归互斥体。确保您不要尝试递归地锁定它。
  2. 使用互斥锁来保护对容器 cb 的访问。
  3. 在等待过程中使用 while 循环来防止虚假唤醒。
  4. 使用更便宜的 condition_variable 而不是更昂贵(且更灵活)的 condition_variable_any。在你的例子中我没有看到后者的必要性。

Assuming you are using a recent version of boost, boost::condition is the same thing as boost::condition_variable_any, which I believe is the same thing as std::condition_variable_any.

If all that is true, or at least approximately true, your code should compile, but will probably deadlock if you call cond.wait(mutex) with mutex recursively locked.

I recommend instead:

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

// In one thread

for(;;)
{
    D * d = nullptr;

    boost::unique_lock<boost::mutex> lock( mutex );
    while( cb.pop(d) ) 
    {

    }
    while (cb.empty())
       cond.wait( lock );
}

// In another thread

while(1)
{
    getchar();

    for( int i = 0 ; i < 1000 ; ++i )
    {
        boost::lock_guard<boost::mutex> lock( mutex );
        cb.push(new D(i));           
        cond.notify_one();
    }
}

And if your implementation supports it, substitute std for boost. This:

  1. Doesn't use a recursive mutex. Be sure you don't try to lock it recursively.
  2. Uses the mutex to protect access to your container cb.
  3. Uses a while loop around your wait to guard against spurious wakeups.
  4. Uses the much cheaper condition_variable instead of the more expensive (and more flexible) condition_variable_any. I'm not seeing the need for the latter in your example.
肩上的翅膀 2024-12-01 17:14:45

正确 - 你需要一个互斥锁;其目的是确保多个消费者与一个生产者同步。

另请参阅 http://www.boost.org/ doc/libs/1_41_0/doc/html/thread/synchronization.html

Correct - you need one mutex; it's purpose will be to make sure that multiple consumers are synchronized with the respect to your one producer.

Also, see http://www.boost.org/doc/libs/1_41_0/doc/html/thread/synchronization.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文