gpt4 book ai didi

c++ - 此信封实现是否正确使用 C++11 原子?

转载 作者:行者123 更新时间:2023-12-01 20:27:05 25 4
gpt4 key购买 nike

我编写了一个简单的“信封”类,以确保我正确理解 C++11 原子语义。我有一个 header 和一个有效负载,编写器清除 header ,填充有效负载,然后用递增的整数填充 header 。这个想法是,读者可以读取 header ,memcpy 出有效负载,再次读取 header ,如果 header 相同,则读者可以假设他们成功复制了有效负载。读者可能会错过一些更新,但这对他们来说是不好的,因为他们会得到一个 splinter 的更新(其中存在来自不同更新的字节的混合)。只有一个读者和一个作者。

写入器使用释放内存顺序,读取器使用获取内存顺序。

memcpy 是否存在通过原子存储/加载调用重新排序的风险?或者负载可以相互重新排序吗?这对我来说永远不会中止,但也许我很幸运。

#include <iostream>
#include <atomic>
#include <thread>
#include <cstring>

struct envelope {
alignas(64) uint64_t writer_sequence_number = 1;
std::atomic<uint64_t> sequence_number;
char payload[5000];

void start_writing()
{
sequence_number.store(0, std::memory_order::memory_order_release);
}

void publish()
{
sequence_number.store(++writer_sequence_number, std::memory_order::memory_order_release);
}

bool try_copy(char* copy)
{
auto before = sequence_number.load(std::memory_order::memory_order_acquire);
if(!before) {
return false;
}
::memcpy(copy, payload, 5000);
auto after = sequence_number.load(std::memory_order::memory_order_acquire);
return before == after;
}
};

envelope g_envelope;

void reader_thread()
{
char local_copy[5000];
unsigned messages_received = 0;
while(true) {
if(g_envelope.try_copy(local_copy)) {
for(int i = 0; i < 5000; ++i) {
// if there is no tearing we should only see the same letter over and over
if(local_copy[i] != local_copy[0]) {
abort();
}
}
if(messages_received++ % 64 == 0) {
std::cout << "successfully received=" << messages_received << std::endl;
}
}
}
}

void writer_thread()
{
const char alphabet[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
unsigned i = 0;
while(true) {
char to_write = alphabet[i % (sizeof(alphabet)-1)];
g_envelope.start_writing();
::memset(g_envelope.payload, to_write, 5000);
g_envelope.publish();
++i;
}
}

int main(int argc, char** argv)
{
std::thread writer(&writer_thread);
std::thread reader(&reader_thread);

writer.join();
reader.join();

return 0;
}

最佳答案

这称为 seqlock;它存在数据竞争,仅仅是因为对 memsetmemcpy 的调用存在冲突。有人建议提供类似 memcpy 的工具来使此类代码正确; most recent不太可能出现在 C++26 之前(即使获得批准)。

关于c++ - 此信封实现是否正确使用 C++11 原子?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58088943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com