gpt4 book ai didi

c++ - 这里是否需要 volatile

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:38 24 4
gpt4 key购买 nike

我正在实现一个“序列锁”类,以允许对数据结构进行锁定写入和无锁定读取。

将包含数据的结构包含序列值,该序列值将在写入发生时递增两次。写作开始前一次,写作完成后一次。作者在读者之外的其他线程上。

这是保存数据拷贝的结构,序列值如下所示:

template<typename T>
struct seq_data_t
{
seq_data_t() : seq(0) {};
int seq; <- should this be 'volatile int seq;'?
T data;
};

整个序列锁类在循环缓冲区中持有该结构的 N 个拷贝。写入线程总是覆盖循环缓冲区中最旧的数据拷贝,然后将其标记为当前拷贝。写入是互斥锁。

读取功能不锁定。它尝试读取数据的“当前”拷贝。它在读取之前存储“seq”值。然后它读取数据。然后它再次读取 seq 值,并将其与第一次读取的值进行比较。如果seq值没有变化,则认为read是好的。

由于写入线程可以在读取发生时更改“seq”的值,我认为 seq 变量应标记为 volatile,以便读取函数在读取数据后显式读取值。

读取函数看起来是这样的:它将在 writer 以外的线程上运行,并且可能在多个线程上运行。

    void read(std::function<void(T*)>read_function)
{
for (;;)
{
seq_data_type<T>* d = _data.current; // get current copy
int seq1 = d->seq; // store starting seq no
if (seq1 % 2) // if odd, being modified...
continue; // loop back

read_function(&d->data); // call the passed in read function
// passing it our data.


//??????? could this read be optimized out if seq is not volatile?
int seq2 = d->seq; // <-- does this require that seq be volatile?
//???????

if (seq1 == seq2) // if still the same, good.
return; // if not the same, we will stay in this
// loop until this condition is met.
}
}

问题:

1) seq 在这种情况下必须是易变的吗?

2) 在具有多个成员的结构的上下文中,只有 volatile 限定变量是 volatile,而不是其他成员?也就是说,如果我只在结构中将它标记为 volatile,那么它只是 'seq' volatile 吗?

最佳答案

不要使用 volatile , 使用 std::atomic<> . volatile旨在用于与内存映射硬件交互,std::atomic<>旨在用于线程同步。为工作使用正确的工具。

好的特点std::atomic<>实现:

  • 它们对于标准整数类型是无锁的(通常是 long long 以内的所有类型)。

  • 它们适用于任何数据类型,但会对复杂数据类型使用透明互斥体。

  • 如果 std::atomic<>是无锁的,它会插入正确的内存屏障/栅栏以实现正确的语义。

  • std::atomic<> 的操作无法优化,毕竟它们是为线程间通信而设计的。

关于c++ - 这里是否需要 volatile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48749643/

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