一些可帮助我确保了解互斥量的问题

时间:2019-07-12 08:14:26

标签: c++ multithreading mutex

大家好, 我对互斥锁有一些疑问(主题已经很具体了)。因此,我需要确保不要误解(https://en.cppreference.com/w/cpp/thread/mutex):

1)我想确保一个std :: mutex不能同时在2个线程之间共享。是真的吗?

2)如果两个随机线程同时询问互斥体,会发生什么情况?

3)根据我的理解,当一个线程使用互斥锁时,它将阻止任何其他线程同时修改全局变量。是一个很好的理解吗?

对于上述任何一个问题,我可以纠正吗?

感谢您。

4 个答案:

答案 0 :(得分:3)

您可能应该更深入地了解互斥体(互斥体还是mutices?),因为它不仅是c ++的概念,而且还是计算机科学的一个整体。要回答您的问题:

  1. 是的,的确如此,这就是关于互斥锁的全部要点。在任何时间点,只有一个线程可以拥有互斥锁。
  2. 其中一个线程将获得互斥锁,而另一个则不会。即使访问是在同一物理时间在多个物理核心上进行的,实现也将照顾到这一点。
  3. 不完全是,您始终可以选择忽略互斥对象,并且仍然可以更改这些变量。您如何解决并发问题取决于您。

编辑

我认为某些语言提供的容器包装变量的方式使得它们一次只能被一个线程读取。我认为它们在Java中称为Monitors。

一般概念:

std::mutex m;
int globalVar;

void foo()
{
//Acquire lock or wait, if another thread already acquired the lock.
mutex.lock();
//At any given time this code will be executed by one thread only (or none)
globalVar = bar();
mutex.unlock();
}

//However you can choose to ignore the mutex...
void evilFoo()
{
  //This can be executed by multiple threads at the same time (even parallel to foo())
  globalVar = bar();
}

答案 1 :(得分:2)

1)应该共享。否则您将如何使用它?

编辑:好的,似乎这个问题有些误导。在这种情况下,“共享”是什么意思?

Edit2:如果“共享”是指一个互斥锁可以由多个线程持有,那么答案是:这不会发生。

2)即使它恰好发生在两个不同内核上的同一物理时间,也会有一些仲裁机制将互斥量提供给一个或另一个线程。

3)否。当 other 线程使用互斥锁时,您知道,您将无法修改受此互斥锁保护的变量而不会产生任何后果,因此应编写代码,以便没有这样的修改。但是互斥体本身并没有防止这种修改。当然,如果不同时持有互斥体,也不应读取此类变量。

答案 2 :(得分:1)

假设爱丽丝给鲍勃5件东西。您将拥有类似的代码。

alice -= 5;
bob +=5;

我们不希望出现这样的情况:我们从爱丽丝(Alice)中删除了5个,但没有将这5个交给鲍勃(Bob)。

std::thread使用操作系统支持来抢占式多线程。这意味着操作可能会在任何时间点中断线程并安排花药。在多核计算机上,它们甚至可以同时运行。这意味着线程可能会看到不一致的数据。

互斥量是一个操作系统对象,其作用是确保每次只有一个线程可以访问代码的关键部分。

因此,当线程1进入互斥量时,它将增加互斥量的访问计数。当下一个线程尝试输入互斥量时,它将检测到访问计数不为零。然后,操作系统将挂起线程。

当第一个线程释放互斥量时,其他线程将再次变为可运行状态。这意味着操作系统可以安排它们现在运行还是稍后运行,具体取决于其优先级。

然后,新运行的线程可能会尝试使用与上述相同的规则输入互斥锁。

这意味着,如果使用了通用互斥锁,则任何两个线程都不能同时输入受该互斥锁保护的代码。

答案 3 :(得分:0)

1)它们可以共享,但互斥锁可用于防止线程同时访问您想要仅一次由一个线程访问和修改的资源。

2)互斥锁的语义是两个线程不能同时锁定同一互斥锁。

3)互斥锁会阻止任何其他线程同时修改在锁定互斥锁之后处理的资源,直到您解锁互斥锁为止。全局变量就是其中之一。