考虑一个简单的(在我的情况下是全局)变量:
int i;
Run Code Online (Sandbox Code Playgroud)
在某处访问此变量
pthread_mutex_lock(i_mutex);
if(i == other value) {
do_something();
}
pthread_mutex_unlock(i_mutex);
Run Code Online (Sandbox Code Playgroud)
另一个线程i 在保持时更新i_mutex.编译器可以缓存值,i所以我没有得到最近的值?一定i是不稳定的?
我想在一个线程中分配内存,并安全地 "释放"指向另一个线程的指针,以便它可以读取该内存.
我正在使用一种翻译成C语言的高级语言.高级语言有线程(未指定的线程API,因为它是跨平台的 - 见下文)并支持标准的C多线程原语,如原子比较交换,但它没有真正记录(没有用法示例).这种高级语言的限制是:
现在,对于大型(不希望复制)或可变大小(我认为数组大小是类型的一部分)消息,这是不切实际的.我想发送这样的消息,这里是我想要实现它的大纲:
我需要知道如何确保这没有数据竞争.我的理解是我需要使用内存栅栏,但我不完全确定哪一个(ATOMIC_RELEASE,...)以及循环中的位置(或者我是否需要任何内容).
因为我的高级语言需要跨平台,所以我需要得到答案:
pthread_mutex_init和pthread_mutex_lock+pthread_mutex_unlockInitializeCriticalSection和EnterCriticalSection+LeaveCriticalSection如果它有帮助,我假设以下架构:
并使用以下编译器(您可以假设所有这些编译器的"最近"版本):
到目前为止,我只在Windows上构建,但是当应用程序完成后,我希望以最少的工作将其移植到其他平台.因此,我试图从一开始就确保跨平台兼容性.
这是我假设的工作流程:
在解释如何使用Boost实现读/写锁时,这个线程是金牌.它似乎相对简单,我真的很喜欢它,但它似乎也使用一个非命名的锁,我需要一个进程间解决方案(不需要是可移植的,可以只有Windows).
有没有办法进行进程间shared_mutex?我看到有一个,named_mutex但我不能让它与shared_lock其他锁一起工作.
任何指针都表示赞赏.
[编辑]
与此同时,我遇到了这个几乎击中头部钉子的线程.我有两个问题:
named_upgradable_mutex但我不太确定)和仍然欢迎评论或好的解决方案.
据我所知,函数调用充当编译器障碍,但不作为CPU障碍.
本教程说明如下:
获取锁意味着获取语义,而释放锁意味着释放语义!其间的所有内存操作都包含在一个漂亮的小屏障三明治中,防止任何不希望的内存重新排序跨越边界.
我假设上面的引用是关于CPU重新排序而不是编译器重新排序.
但我不明白互斥锁和解锁如何导致CPU赋予这些函数获取和释放语义.
例如,如果我们有以下C代码:
pthread_mutex_lock(&lock);
i = 10;
j = 20;
pthread_mutex_unlock(&lock);
Run Code Online (Sandbox Code Playgroud)
上面的C代码被翻译成以下(伪)汇编指令:
push the address of lock into the stack
call pthread_mutex_lock()
mov 10 into i
mov 20 into j
push the address of lock into the stack
call pthread_mutex_unlock()
Run Code Online (Sandbox Code Playgroud)
现在是什么阻止了CPU重新排序mov 10 into i以及mov 20 into j 上方call pthread_mutex_lock()或下方call pthread_mutex_unlock()?
如果它是call阻止CPU进行重新排序的指令,那么为什么我引用的教程使它看起来像是互斥锁和解锁函数来阻止CPU重新排序,为什么我引用的教程没有说任何函数调用会阻止CPU重新排序吗?
我的问题是关于x86架构.