我在无锁的SPSC中发现了一个奇怪的现象

问题描述 投票:0回答:1

我尝试使用无锁技术实现 SPSC,但遇到了奇怪的分段错误。代码如下:

#include <iostream>
#include <thread>
#include <vector>
#include <atomic>

#define MATTER_NUM  10000
#define BUF_LEN 1024

uint64_t RingBuffer[BUF_LEN];
//uint32_t m_buffer[BUF_LEN];

std::atomic<uint64_t> head(0);
std::atomic<uint64_t> tail(0);


bool Push(const uint64_t &data) {
         uint64_t tmp_tail = tail.load(std::memory_order_relaxed);
         if ((tmp_tail + 1) % BUF_LEN == head.load(std::memory_order_acquire)) return false;
         RingBuffer[tmp_tail + 1] = data;
         tail.store((tmp_tail + 1) % BUF_LEN, std::memory_order_release);
         return true;

}

bool Pop(uint64_t &data) {
      static uint64_t cnt = 0;
      uint64_t tmp_head = head.load(std::memory_order_relaxed);
      if (tmp_head == tail.load(std::memory_order_acquire)) return false;
      data = RingBuffer[tmp_head];
      head.store((tmp_head + 1) % BUF_LEN, std::memory_order_release);
      cnt = (tmp_head + 1) % BUF_LEN;
      return true;
}

int Producer() {
    for (int i = 0; i < MATTER_NUM; i++) {
        while (!Push(i));
    }
    return 0;
}

int Consume() {
    for (int i = 0; i < MATTER_NUM; i++) {
        uint64_t data = -1;
        while (!Pop(data));
        std::cout << data << std::endl;
    }
    return 0;
}

int main()
{
    std::thread t1(Producer), t2(Consume);
    t1.join();
    t2.join();
    return 0;
}

有一个奇怪的现象。当我取消第10行中的注释“uint32_t m_buffer[BUF_LEN]”时,代码神奇地正常运行!我不明白为什么会发生这种情况。

内置 g++ (GCC) 7.5.0: g++ -std=c++11 -pthread main.cpp && ./a.out

c++ gcc concurrency thread-safety atomic
1个回答
0
投票

RingBuffer[tmp_tail + 1] = data;
- 不需要
%BUF_LEN
吗?看来您偶尔会出现缓冲区溢出的情况。

© www.soinside.com 2019 - 2024. All rights reserved.