gpt4 book ai didi

c中的并发变量访问

转载 作者:行者123 更新时间:2023-12-04 21:27:40 26 4
gpt4 key购买 nike

我对 C 中的并发编程有一个相当具体的问题。我对此进行了相当多的研究,但看到了几个相互矛盾的答案,所以我希望得到一些澄清。我有一个类似于以下的程序(抱歉,代码块过长):

typedef struct {
pthread_mutex_t mutex;
/* some shared data */
int eventCounter;
} SharedData;

SharedData globalSharedData;

typedef struct {
/* details unimportant */
} NewData;

void newData(NewData data) {
int localCopyOfCounter;

if (/* information contained in new data triggers an
event */) {
pthread_mutex_lock(&globalSharedData.mutex);
localCopyOfCounter = ++globalSharedData.eventCounter;
pthread_mutex_unlock(&globalSharedData.mutex);
}
else {
return;
}

/* Perform long running computation. */

if (localCopyOfCounter != globalSharedData.eventCounter) {
/* A new event has happened, old information is stale and
the current computation can be aborted. */
return;
}

/* Perform another long running computation whose results
depend on the previous one. */

if (localCopyOfCounter != globalSharedData.eventCounter) {
/* Another check for new event that causes information
to be stale. */
return;
}

/* Final stage of computation whose results depend on two
previous stages. */
}

有一个线程池为传入数据的连接提供服务,因此可以同时运行多个 newData 实例。在多处理器环境中,我知道在正确处理此代码的计数器部分时存在两个问题:阻止编译器将共享计数器副本缓存在寄存器中,以便其他线程看不到它,并强制CPU 及时将计数器值的存储写入内存,以便其他线程可以看到它。我不希望在计数器检查周围使用同步调用,因为部分读取计数器值是可以接受的(它将产生与本地副本不同的值,这应该足以断定事件已发生)。将 SharedData 中的 eventCounter 字段声明为 volatile 就足够了,还是我需要在这里做其他事情?还有更好的方法来处理这个吗?

最佳答案

不幸的是,C 标准很少提及并发性。但是,大多数编译器(无论如何,gcc 和 msvc)都会将 volatile 读取视为具有 acquire semantics -- volatile 变量将在每次访问时从内存中重新加载。这是可取的,您现在的代码可能最终会比较缓存在寄存器中的值。如果这两个比较都被优化了,我什至不会感到惊讶。

所以答案是肯定的,制作 eventCounter易 volatile 的。或者,如果您不想过多地限制您的编译器,您可以使用以下函数来执行 eventCounter 的读取。 .

int load_acquire(volatile int * counter) { return *counter; }

if (localCopy != load_acquire(&sharedCopy))
// ...

关于c中的并发变量访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/871855/

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