提问者:小点点

STL互斥体的行为不符合要求


我在这方面找不到太多,所以我想我会发表我自己的问题。

我有一个执行循环的线程,每次都锁定一个互斥体。问题是,循环之间没有足够的时间让另一个线程锁定互斥锁。下面是一些复制我的问题的代码:

#include <thread>
#include <mutex>
#include <iostream>
#include <functional>

volatile bool bar;

void foo( std::mutex& m )
{
    while( true )
    {
        std::unique_lock<std::mutex> lock( m );

        if( bar )
            break;

        std::cout << "Hello World" << std::endl;
 
        std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
    }
}

int main( int argc, char** argv )
{
    bar = false;

    std::mutex m;

    std::thread t( std::bind( foo, std::ref( m ) ) );

    std::this_thread::sleep_for( std::chrono::seconds( 5 ) );

    std::cout << "Terminating thread..." << std::endl;

    {
        std::unique_lock<std::mutex> lock( m );

        bar = true;
    }

    t.join();
}

和示例输出:

Hello World
Hello World
Hello World
Hello World
Hello World
Terminating thread...
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World

我确信在使用互斥体之前使用一个简单的sleep命令可以解决我的问题,但是由于我的应用程序的高循环速率和低延迟要求,如果有必要,我希望避免这样做。

有什么想法吗?有没有通知主线程的方法?std::mutex是这里的最佳选择吗?

谢了。


共1个答案

匿名用户

必须在锁周围添加作用域,否则互斥体在休眠时仍被锁定:

void foo( std::mutex& m )
{
    while( true )
    {
        {
            std::unique_lock<std::mutex> lock( m );
            if( bar )
                break;
        }
        // The mutex is now unlocked

        std::cout << "Hello World" << std::endl;
 
        std::this_thread::sleep_for( std::chrono::seconds( 1 ) );
    }
}