一些问题可以帮助我确保了解互斥锁 [关闭]
Posted
技术标签:
【中文标题】一些问题可以帮助我确保了解互斥锁 [关闭]【英文标题】:Some questions to help me to be sure to understand mutex [closed] 【发布时间】:2019-07-12 08:14:26 【问题描述】:大家好, 我对互斥锁有一些疑问(主题已经很具体)。所以,我需要确保不要有误解(https://en.cppreference.com/w/cpp/thread/mutex):
1) 我想确定一个 std::mutex 不能同时在 2 个线程之间共享。是真的吗?
2) 如果两个独立线程随机同时询问互斥锁,会发生什么?
3) 据我了解,当一个线程获取互斥体时,它会阻止任何其他线程同时修改全局变量。好理解吗?
如果我对这些问题中的任何一个问题,您能纠正吗?
我会感谢你的。
【问题讨论】:
是的。不会发生。是的。 1) 是的。也可以查看 shared_mutex 。 2)互斥体处理它,你不应该担心 3)在互斥体被释放之前,任何带有互斥体的代码都不能被另一个线程同时执行 @super,当一个线程“获取互斥锁”时,绝对不会阻止其他线程“同时修改全局变量”。除了阻止其他线程“获取”同一个互斥体之外,它不会阻止任何事情。 【参考方案1】:您可能应该进一步阅读有关互斥锁(互斥锁?互斥锁?)的信息,因为它不仅仅是 c++ 的概念,而是一般计算机科学的概念。回答您的问题:
-
是的,没错,这就是互斥锁的全部意义所在。在任何时间点,只有一个线程可以拥有互斥锁。
其中一个线程将获得互斥锁,另一个则不会。即使在同一物理时间在多个物理内核上进行访问,实施也会处理此问题。
不完全是,您始终可以选择忽略互斥锁并仍然更改这些变量。如何解决并发问题取决于您。
编辑
我认为有些语言提供了包装变量的容器,使得它们一次只能被一个线程读取。我认为它们在 Java 中被称为监视器。
一般概念:
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();
【讨论】:
【参考方案2】:1) 它应该被分享。不然你会怎么用???
编辑:好的,这个问题似乎有点误导。在这种情况下,您所说的“共享”是什么意思?
Edit2:如果“共享”是指一个互斥锁可以由多个线程持有,那么答案是:这不可能发生。
2) 即使它发生在两个不同的内核上的完全相同的物理时间,也会有一些仲裁机制将互斥锁分配给一个或其他线程。
3) 不会。当 other 线程使用互斥锁时,您知道不能修改受此互斥锁保护的变量而不会产生任何后果,并且应该编写这样的代码是没有这样的修改。但互斥锁本身绝不会阻止此类修改。当然你不应该在没有持有互斥锁的情况下读取这些变量。
【讨论】:
我认为“共享”是指两个线程可以同时获取一个互斥锁的锁。至少我是这样理解的。 @churill :你是对的。谢谢【参考方案3】:假设 Alice 给 Bob 5 样东西。你会有类似的代码。
alice -= 5;
bob +=5;
我们不希望出现这样的情况:我们从 Alice 身上移除了 5 个,但没有将 5 个给 Bob。
std::thread
使用操作系统支持抢占式多线程。这意味着该操作可能会在任何时间点中断线程并安排花药。在多核机器上,它们甚至可以同时运行。这意味着线程可能会看到不一致的数据。
互斥锁是一个操作系统对象,它的作用是确保一次只有一个线程可以访问代码的关键部分。
所以当线程 1 进入互斥体时,它会增加互斥体的访问计数。当下一个线程尝试进入互斥体时,它检测到访问计数不为零。操作系统然后挂起线程。
当第一个线程释放互斥锁时,其他线程再次变为可运行。这意味着操作系统可能会根据其优先级安排它们现在或稍后运行。
然后,新可运行的线程可能会尝试使用与上述相同的规则进入互斥锁。
这意味着只要使用一个通用的互斥锁,任何两个线程都不能同时进入受互斥锁保护的代码。
【讨论】:
【参考方案4】:1) 它们可以共享,但互斥锁用于防止线程同时访问您希望一次只能由一个线程访问和修改的资源。
2) 互斥锁的语义是两个线程不能同时锁定同一个互斥锁。
3) 互斥锁阻止任何其他线程同时修改互斥锁锁定后处理的资源,直到您解锁互斥锁为止。全局变量就是其中之一。
【讨论】:
锁定一个互斥锁只能防止一件事:它可以防止其他线程锁定同一个互斥锁。它不会阻止其他任何事情。如果开发人员希望在互斥锁被锁定时阻止其他线程使用某些资源,那么开发人员完全有责任为这些线程编写代码,以便它们以这种方式运行。 感谢所罗门在这里的帮助以及在我的其他问题中的帮助 @Solomon 慢是真的,我只是举了一个使用互斥锁的例子,这是常见的。以上是关于一些问题可以帮助我确保了解互斥锁 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章