c++ - Win32 C++ 中的无锁双端队列

标签 c++ multithreading winapi interlocked lockless

我对无锁数据结构还很陌生,所以我写了一个练习(我希望它的功能是)一个有界无锁双端队列(还没有调整大小,只是想让基本情况起作用)。我只是想从知道自己在做什么的人那里得到一些确认,以确定我是否有正确的想法和/或我如何改进它。

class LocklessDeque
{
  public:

    LocklessDeque() : m_empty(false),
                      m_bottom(0),
                      m_top(0) {}


    ~LocklessDeque()
    {
      // Delete remaining tasks
      for( unsigned i = m_top; i < m_bottom; ++i )
        delete m_tasks[i];
    }


    void PushBottom(ITask* task)
    {
      m_tasks[m_bottom] = task;

      InterlockedIncrement(&m_bottom);
    }


    ITask* PopBottom()
    {
      if( m_bottom - m_top > 0 )
      {
        m_empty = false;

        InterlockedDecrement(&m_bottom);

        return m_tasks[m_bottom];
      }

      m_empty = true;

      return NULL;
    }


    ITask* PopTop()
    {
      if( m_bottom - m_top > 0 )
      {
        m_empty = false;

        InterlockedIncrement(&m_top);

        return m_tasks[m_top];
      }

      m_empty = true;

      return NULL;
    }


    bool IsEmpty() const
    {
      return m_empty;
    }

  private:

    ITask* m_tasks[16];

    bool m_empty;

    volatile unsigned m_bottom;
    volatile unsigned m_top;

};

最佳答案

看着这个我会认为这会是一个问题:

void PushBottom(ITask* task)
{
  m_tasks[m_bottom] = task;
  InterlockedIncrement(&m_bottom);
}

如果在实际的多线程环境中使用它,我认为您在设置 m_tasks[m_bottom] 时会发生冲突。想一想如果您有两个线程同时尝试执行此操作会发生什么 - 您无法确定哪个线程实际设置了 m_tasks[m_bottom]。

查看 this article这是对无锁队列的合理讨论。

关于c++ - Win32 C++ 中的无锁双端队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1835106/

相关文章:

c# - 在 ASP.NET Web 应用程序中创建线程的正确方法

c++ - 如何在 win32 C++ 应用程序中为具有 HANDLE 作为成员的类编写复制构造函数?

c++ - 在 c++ builder 中启动时打开两个窗体

C++ 选择文件夹,包含文件

c# - 具有引用类型的代码线程安全吗?

c++ - 无法使用 C++ 中的 Window 蓝牙 API 连接到蓝牙设备

winapi - 处理 Windows 消息的更好方法?

C++ 程序函数

c++ - 用 C++ 风格的注释替换 C 风格的注释

java - Java中使用RocksDB执行并行写入时出现 "Failed to create lock"异常