C++同步定时等待

C++ Synchronization timed wait

我有一个多线程 C++ 应用程序。我想用 busy/free 状态标记一个对象,例如:

我实现了下面的要求,有更好的方法吗?

#include <condition_variable>
#include <mutex>  
#include <atomic>
#include <thread>
#include <iostream>

std::mutex m_Mutex;
std::condition_variable m_ConditionVariable;
std::atomic_flag m_BusyFlag;

const int TRY_LOCK_TIMEOUT_MILLIS = 1;

bool IsFree() { return !m_BusyFlag.test_and_set(); }

bool LockSeqNum(bool timed_wait)
{
    std::cout <<" TRY LockSeqNum, thread= " << std::this_thread::get_id() << endl;
    bool success = true;
    std::unique_lock<std::mutex> lck(m_Mutex);
    if (m_BusyFlag.test_and_set())
    {
        if (timed_wait)
            success = !m_ConditionVariable.wait_for(lck, std::chrono::milliseconds(TRY_LOCK_TIMEOUT_MILLIS), [] { return IsFree(); });
        else
            m_ConditionVariable.wait(lck, [] { return IsFree(); });
    }

    std::cout << "LockSeqNum " << success << "  thread = " << std::this_thread::get_id() << endl;
    return success;
}

void UnlockSeqNum()
{
    std::cout << " UNLockSeqNum, thread= " << std::this_thread::get_id() << endl;
    std::unique_lock<std::mutex> lck(m_Mutex);
    m_BusyFlag.clear();
    m_ConditionVariable.notify_one();
}

如果你想允许 IsFree() 的外部,代码就可以了。否则,正如 Yakk 在评论中指出的那样,将 m_BusyFlag 声明为简单布尔值就足够了。 atomic_flag 在那里是开销,因为变量总是在互斥锁下访问。

您拥有使用条件等待所需的最少工具:条件变量、互斥锁和用于等待其状态的普通变量。因此,只有当线程需要调用 UnlockSeqNum 时,才可能实现更简单的实现(简单锁定),该线程之前调用过 LockSeqNum。