互斥锁是否在全球范围内保护变量?

时间:2016-06-13 14:15:17

标签: multithreading parallel-processing mutex atomic

互斥锁是否全局锁定对变量的访问,或仅锁定与锁定的互斥锁相同的范围?

请注意,我必须更改此问题的标题,因为很多答案似乎与我的要求相混淆。这不是关于"互斥对象"的范围(全局或其他)的问题,而是关于变量的范围是什么"锁定"通过互斥锁。

我相信答案是互斥锁可以锁定对所有变量的访问,即;所有全局和本地范围的变量。 (这是因为互斥锁阻塞线程执行而不是访问特定的内存区域。)

我试图了解互斥锁。

我试图了解内存的哪些部分,或等价的,哪些变量,互斥锁会锁定。

但是,通过在线阅读我的理解是,互联网执行锁定内存,它们锁定(或阻止)同时运行的线程,这些线程都是同一进程的成员。 (这是正确的吗?)

https://mortoray.com/2011/12/16/how-does-a-mutex-work-what-does-it-cost/

所以我的问题变得简单"互斥是全局的吗?"

......或者他们或许是#34;一般来说是全球性的,但是stackoverflow社区可以想象一些他们不是的特殊情况?"

在最初考虑我的问题时,我对以下示例中显示的内容感兴趣。

// both in global scope, this mutex will lock any global scope variable?
int global_variable;
mutex global_variable_mutex;

int main()
{
    // one thread operates here and locks global_variable_mutex
    // before reading/writing

    {
        // local variables in a loop
        // launch some threads here, and wait later
        int local_variable;
        mutex local_variable_mutex;
        // wait for launched thread to return

        // does the mutex here prevent data races to the variable
        // global_variable ???
    }
}

可以假设这是C ++或C的伪代码,或任何其他类似相关的语言。

3 个答案:

答案 0 :(得分:0)

  

所以我的问题变得简单"互斥是全球性的?"

没有。互斥锁具有lock()和unlock()方法,并且互斥锁唯一能做的就是它的lock()调用(来自任何线程)只要另一个线程锁定了该互斥锁就不会返回。当持有锁定互斥锁的线程调用unlock()时,即lock()调用将在第一个线程中返回。这样可以保证只有一个线程会持有互斥锁(即在任何给定时间在其lock()调用和解锁调用()之间的区域内执行)。

真的就是这一切。因此,互斥锁只会影响在该特定互斥锁上调用lock()的线程,而不会影响其他内容。

答案 1 :(得分:0)

正如您的问题所示,我认为您的问题与任何编程语言无关。

首先,了解什么是互斥量及其工作原理非常重要? 互斥锁是二进制信号量。那么什么是信号量? 信号量是具有以下属性的整数

  • 您可以将其初始化为任何允许的值(对于互斥锁,它是1或0)。
  • 线程可以访问信号量,它可以递增或递减其整数值。
  • 当一个线程递减时, 如果结果为正或零,该线程可以继续其进程。 如果结果为负,该线程将等待,并且任何后续线程都不会进一步减少信号量值。
  • 如果一个线程递增它,(在这种情况下,信号量值将为正或0)并且结果为0,其中一个等待线程可以继续执行。

因此,当线程尝试访问共享资源时,它将减少互斥量值(从0开始,以便其他线程正在等待)。当它完成时,它将增加互斥量值(以便等待线程可以继续)。这是通过互斥(二进制信号量)实现访问控制的方式。

我想你明白你的问题在这里是不适用的。作为

的简单答案
  

所以我的问题变得简单"互斥是全球性的?"

简直就是NO。

答案 2 :(得分:-1)

互斥锁具有您为其分配的任何范围。它可以根据您声明的位置和方式再次为全局或本地。例如,如果您在可以全局访问全局内存的地方声明互斥锁,那么它确实是全局的。如果您在函数或私有类作用域级别声明它,那么只有该函数或类才能访问它。

也就是说,为了对同步有用,需要在可以由需要在其上进行同步的线程访问的范围中声明互斥锁。无论是全局范围还是局部范围,都取决于您的程序结构。我建议在线程可访问的最高范围内声明它但不高。

在您的特定示例中,互斥锁确实是全局的,因为您已在全局内存中声明它。