2017-08-13 94 views
0

问题很简单。 是否/应该在多线程中使用的变量是volatile,甚至在C中的关键部分(即互斥量,信号量)中被访问?为什么/为什么不?带互斥量和信号量的volatile关键字

#include <pthread.h> 

    volatile int account_balance; 
    pthread_mutex_t flag = PTHREAD_MUTEX_INITIALIZER; 

    void debit(int amount) { 
    pthread_mutex_lock(&flag); 
    account_balance -= amount;//Inside critical section 
    pthread_mutex_unlock(&flag); 
} 

这个例子或等价的信号量思考怎么样?

+0

https://stackoverflow.com/a/78221/635608 – Mat

+0

为什么/为什么不呢? @Mat – concurrencyboy

+0

你想让我重新键入英特尔在这里链接的文章吗?或重新输入其他答案? – Mat

回答

1

是否应该在多线程中使用的变量在C中的临界区(即互斥量,信号量)中是易变的?为什么/为什么不?

volatile是并发性逻辑无关,因为它不足够

其实,这是不是真的 - volatile不无关系,因为它可以在你的代码隐藏并发问题,所以它的工作原理“大部分时间”。

所有挥发性所做的就是告诉编译器“这个变量可以执行的当前线程外部改变”。挥发性决不会强制执行任何顺序,原子性或 - 关键 - 可视性。正因为线程2 CPU A改变int x,这并不意味着在CPU d线1甚至可以看到在任何特定时间的变化 - 它有它自己的缓存值,并volatile意味着几乎对于任何内存的一致性,因为它不保证排序。

在英特尔文章挥发性底部的最后注释:Almost Useless for Multi-Threaded Programming最好说它:

如果您只是添加“挥发”到被线程以为之间共享 变量解决您的共享数据问题没有 困扰,为什么它可能不会,你最终会收获你应得的回报。

是的,无锁码可以利用volatile。此类代码由可能编写关于使用volatile,多线程代码以及其他有关编译器的非常详细主题的教程编写。

1

不,volatile不应该用于在pthreads同步函数保护下访问的共享变量,如pthread_mutex_lock()

原因在于POSIX提供的同步功能本身可以提供所有必要的编译器障碍和同步以确保一致性(只要您遵循POSIX关于并发访问的规则 - 即您已经使用了pthreads同步函数以确保在另一个线程正在写入或从中读取数据时,没有线程可以写入共享变量)。