在Java中,我们通常使lock变量为final静态,以便仅存在它的一个副本(尽管我记得读过,即使static变量也可以复制到两个方法的调用堆栈中!)
但是我正在处理C和数据同步。我已经声明了一个pthread_mutex_t变量,该变量将锁定N个线程以访问公共资源。
我不确定该变量是否经过重复证明(java中的静态变量的问题可能会或可能不会被复制到两个方法的调用堆栈中)。因为如果它们被编译器复制,那么我担心锁定可能无法正常工作。那么,我们是否需要更多的激进访问修饰符(例如“ volatile”)使其真正地是单数呢?
答案 0 :(得分:5)
不仅没有必要; 不允许。 yourJson.hasOwnProperty('param name')
函数的参数的类型为pthread_mutex_...
,并且需要指向pthread_mutex_t *
对象的有效指针。指向pthread_mutex_t
的指针不会像指向volatile pthread_mutex_t
的指针那样自动转换,因为在需要使用不合格的指针时,该指针不可用。您可以通过强制转换对其进行转换,但是随后您就具有违反函数约定的不确定行为。
答案 1 :(得分:3)
简短的回答:不。 如果您声明的变量是全局变量,那么将只有一个(独立于 volatile 限定符)。 volatile通常用于可能在中断(微控制器)或其他线程的上下文中更改的变量,但不用于锁本身。
在C和Java中,看来 volatile 的含义不同。看看:https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword
C的volatile关键字是一个限定符,在以下情况下将其应用于变量 它被声明。它告诉编译器变量的值 可能随时更改-代码未采取任何措施, 编译器在附近找到。
答案 2 :(得分:0)
要进一步强调为什么需要这样做,可以查看以下示例:
如果您编写这样的内容:
void parallel_function(){
//Example function, this doesn't exist, but it is good to let you understand
pthread_mutex_is_free(&lock);
doStuff();
}
然后pthread_mutex_is_free将在锁定互斥对象之前进行一些检查,以查看该互斥对象是否空闲。 这里有个问题,问题出在编译器优化上,因为对他来说,代码是从单个线程执行的,因此,它可以选择跳过此检查(互斥体是免费的),因为他看到该变量是在之前设置的因为它是免费的,并且从未更改,所以它将始终是免费的,并且这是没有用的,因此在编译后的代码中将其跳过。 因此,使用Volatile强制编译器避免这种检查,基本上是告诉编译器期望此变量进行神奇的更改,从而避免静态优化。