从不同线程使用int64的不同字节安全吗

Is it safe to use different bytes of an int64 from different thread?

本文关键字:字节 安全 线程 int64      更新时间:2023-10-16

例如,有8个线程使用uint64作为共享内存,并在该区域使用不同的字节(无锁(。

一个线程只能访问某个字节,因此不存在字节争用。

在这种情况下,安全吗?从性能角度来看,使用CAS来操作整个整数而不是每个字节更好吗?

不,它通常是不安全的。多字节变量的这些字节不是自己编写的。整个变量被读取、修改和写回。

因此,线程A可以读取它,修改它,然后线程B读取它,线程A写入它,线程B修改和写入它。在这种情况下,来自线程A的更改将丢失。

您需要使用单独的变量或同步机制。

对于性能部分:你必须测试它。不同的代码、硬件、数据大小等会给你不同的答案,告诉你什么是最佳的。根据经验,首先编写简单正确的代码,然后在真正需要时进行优化。

我认为它是安全的。如果我错了,请纠正我。但请记住Mike Acton在他关于严格混叠规则的文章中所写的内容:

通常假定char*可以引用任何对象的别名。因此,将任何类型的指针强制转换为char*类型是非常安全的,如果可能有点不优化的话(对于具有宽加载和存储的体系结构(。

我们可以执行以下操作:

uint64_t shared_64 = 0x0102030405060708;
char* thread_1_char = reinterpret_cast< char* >( &shared_64 );
char* thread_2_char = reinterpret_cast< char* >( &shared_64 ) + 1;
char* thread_3_char = reinterpret_cast< char* >( &shared_64 ) + 2;
char& thread_1_ref = *thread_1_char;
char& thread_2_ref = *thread_2_char;
// and so on
thread_1_ref = 1; // from one thread
//...
thread_2_ref = 2; // from another thread

现在,每个thread_n_ref变量都是一个不同的内存位置,记住主题启动器所说的:

一个线程只能访问某个字节,因此不存在字节争用。

从这个

不同的执行线程总是被允许同时访问(读取和修改(不同的内存位置,没有干扰,也没有同步要求。

我得出结论,从不同的线程访问int64的不同字节是安全的。