gpt4 book ai didi

c - C 中的双重检查锁定模式问题

转载 作者:行者123 更新时间:2023-11-30 20:33:54 25 4
gpt4 key购买 nike

作为所有研究过此问题的人,我已经阅读了这篇论文 http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

我有一个关于在 C 结构上实现 DCLP 时的障碍的问题。这是代码:

typedef struct _singleton_object {
int x;
int y;
} sobject;

static sobject *singleton_object = NULL;

sobject *get_singleton_instance()
{
sobject *tmp = singleton_object;

/* Insert barrier here - compiler or cpu specific or both? */
if (tmp == NULL) {
mutex_lock(&lock); /* assume lock is declared and initialized properly*/
tmp = singleton_object;
if (tmp == NULL) {
tmp = (sobject *)malloc(sizeof(sobject)); /* assume malloc succeeds */
tmp->x = 5;
tmp->y = 7;

/* Insert barrier here - compiler or cpu specific or both ?*/
singleton_object = tmp;
}
mutex_unlock(&lock);
}
return tmp;
}

第一个问题如评论中所述:当论文描述插入屏障时,它仅指编译器、CPU 还是两者都指?我认为两者都是。

我的第二个问题是:是什么阻止编译器在代码中用 singleton_object 替换 tmp ?是什么强制将 singleton_object 加载到 tmp 中,tmp 可能位于编译器生成的代码中的寄存器或堆栈中?如果编译器在每次引用 tmp 时,实际上都会从 &singleton_object 加载到寄存器并丢弃该值,该怎么办?下面引用的论文中的解决方案似乎取决于我们使用局部变量的事实。如果编译器没有将指针变量中的值加载到局部变量tmp,我们又回到了论文中描述的原始问题。

我的第三个问题是:假设编译器确实将 singleton_object 的值本地复制到寄存器或堆栈(即变量 tmp)中,为什么我们需要第一个屏障?函数开头的 tmp = singleton_object 和 if (tmp == NULL) 不应重新排序,因为与 tmp 存在隐式的先读后写依赖关系。另外,即使我们在第一次加载到 tmp 时从 CPU 缓存中读取过时的值,它也应该被读取为 NULL。如果它不为 NULL,则对象构造应该完成,因为构造它的线程/CPU 应该执行屏障,这确保在 singleton_object 具有非 NULL 值之前,x 和 y 的存储对所有 CPU 都是可见的。

最佳答案

  1. When the paper describes insert barriers does it mean just the compiler, CPU or both?

    两个障碍都应该是CPU 障碍(这意味着编译器障碍)。

  2. what prevents the compiler from replacing tmp with singleton_object in the code?

    赋值后的障碍

    sobject *tmp = singleton_object;

    除其他外,还意味着(对于 CPU 和编译器):

    ** 在屏障之前发出的所有读取访问都应在屏障之前完成

    因此,编译器不允许读取屏障后的singleton_object变量而不是读取tmp

  3. If it (singleton_object) is not NULL, then the object construction should be complete, since the thread/CPU that constructs it should execute the barrier, which ensures that the stores to x and y are visible to all CPU's before singleton_object has a non NULL value.

    您需要为实际使用这些“可见”变量xy执行屏障。如果没有屏障,读取线程可能会使用陈旧值。

    通常,不同线程之间的每次同步都需要双方存在某种“屏障”:读取和写入。

关于c - C 中的双重检查锁定模式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43794322/

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