c++同步定时等待

C++ Synchronization timed wait

本文关键字:等待 定时 同步 c++      更新时间:2023-10-16

我有一个多线程c++应用程序。我想将一个对象标记为繁忙/空闲状态,例如:

  • 线程可以切换对象状态
  • 线程必须在任何时候独占访问某些公共成员函数(而其他公共成员函数不需要同步)
  • 如果对象处于忙状态,线程可以选择无限等待或指定时间等待,直到对象空闲。

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

#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。