首页 > 解决方案 > 16位对象数组的memcpy可以在两者之间中断吗

问题描述

全球数据:

uint16_t global_buffer[128];

线程 1:

uint16_t local_buffer[128];
while(true)
{
    ...
    if(data_ready)
        memcpy(global_buffer, local_buffer, sizeof(uint16_t)*128);
}

线程 2:

void timer_handler()
{
    uint16_t value = global_buffer[10];
    //do something with value
}

我的问题是这样做是否安全?我的意思是,是否保证value将获得旧值或新值(如果线程 1 memcpy() 被上下文切换中断)?在更新 16 位值的一个字节而不是第二个字节后,memcpy 是否有可能被中断。在那种情况下,value将是垃圾。

如果 memcpy 操作仅在偶数字节块之间被中断,我认为这是安全的。

平台:仅 x86 和 x86-64(实际上只有 Intel i7 处理器或更新版本)
操作系统:Linux
编译器:gcc

标签: cgccx86thread-safetyatomic

解决方案


这将取决于实施memcpy()- 没有保证。即使您知道该实现使这变得安全,仍然依赖它是不明智的,因此在所有版本和平台上,此代码或模式可能会被重用。

您可以使用您知道是原子的单词副本来实现自己的逐字 16 位副本。如何做到这一点值得提出一个新问题。


推荐阅读