什么是std :: mutex阻止线程修改?

时间:2020-02-05 19:05:46

标签: c++ multithreading thread-safety mutex

mutex.lock()时,.try_lock()锁定了存储器的哪一部分,仅仅是函数还是整个程序被锁定了?

4 个答案:

答案 0 :(得分:3)

除互斥锁外,其他均未锁定。其他所有内容将继续运行(直到尝试锁定已锁定的互斥体为止)。互斥锁仅在那儿,因此两个线程无法同时在互斥锁和互斥锁之间运行代码。

答案 1 :(得分:3)

互斥锁除了自身之外,什么都没有锁定。您可以将互斥锁视为只能从内部解锁的门。当门被锁定时,任何试图锁定互斥锁的线程都将坐在门旁,并等待门后面的当前线程将其解锁并让它们进入。当门未锁定时,则调用{ {1}}您可以进入,关闭并锁上闸门,现在除非解锁并允许它们进入,否则任何线程都无法越过闸门。

答案 2 :(得分:1)

互斥锁不会锁定任何内容。您只需使用互斥锁来与代码的其他部分通信,他们就应该考虑 决定需要保护以防止关闭的多个线程同时进行访问的任何内容。 -现在限制。

您可以将互斥锁视为布尔okToModify之类的东西。每当您要编辑内容时,都要检查okToModify是否为true。如果是这样,则将其设置为false(防止其他任何线程对其进行修改),进行更改,然后将okToModify设置回true,以告诉其他线程您已经完成,并给他们一个修改的机会:

// WARNING! This code doesn't actually work as a lock!
//    it is just an example of the concept.
struct LockedInt {
    bool okToModify; // This would be your mutex instead of a bool.
    int integer;
};

struct LockedInt myLockedInt = { true, 0 };    

...

while (myLockedInt.okToModify == false)
    ; // wait doing nothing until whoever is modifying the int is done.
myLockedInt.okToModify = false; // Prevent other threads from getting out of while loop above.
myLockedInt.integer += 1;
myLockedInt.okToModify = true; // Now other threads get out of the while loop if they were waiting and can modify.

上面的while循环和okToModify = false基本上就是锁定互斥锁的作用,而okToModify = true就是解锁互斥锁的作用。

现在,为什么我们需要互斥体而不使用布尔值?因为一个线程可能与上述三行同时运行。锁定互斥锁的代码实际上保证了等待okToModify成为true和设置okToModify = false的过程只有一次,因此没有其他线程可以进入“行之间”,例如使用特殊的机器代码指令“比较和交换”。

因此,不要不要使用布尔值而不是互斥锁,但是您可以将互斥锁视为一种特殊的线程安全布尔值。 / p>

答案 3 :(得分:0)

m.lock()并没有真正锁定任何东西。它的作用是,它等待获得互斥体的所有权。互斥锁始终是完全由一个线程拥有的,或者它是可用的。 m.lock()等待互斥锁可用,然后以调用线程的名称获取它的所有权。

m.unlock 释放互斥锁(即放弃所有权),导致互斥锁再次可用。


互斥体还执行另一个非常重要的功能。在现代C ++中,当某个线程T对各个内存位置执行一系列不同值的分配序列时,系统无法保证其他线程U,V和W何时会看到这些分配,其他线程是否会看到这些分配发生以线程T执行它们的顺序,甚至其他线程是否会永远查看分配。

有一些非常复杂的规则来管理程序员可以执行的操作,以确保不同的线程看到共享内存对象的一致视图(Google“ C ++内存模型”),但这是一个简单的规则:

保证线程T在释放一些互斥锁M之前所做的任何操作,保证在其他线程U可见 之后,线程U随后锁定相同的互斥锁M。