互斥锁可保证收购订单吗?

最近,一个同事有一个问题,这已经归结为我们认为应用程序中的下一个事件序列 C++ 有两个线程:

线程a包含一个 mutex.

虽然流动和持有 mutex, 流程试图阻止它。 由于它保持,线程暂停。

流并完成他保留的工作 mutex, 从而释放 mutex.

很快就在那个流程之后,应该触摸资源受到保护 mutex, 因此,他再次阻止他。

似乎流动并再次得到了 mutex; 仍然在等待,虽然他 "asked" 首先阻止。

是语义中的这一序列,让我们说 C++11
std::mutex

和 / 或者 pthreads? 我可以诚实地说,我以前从未想过这个方面的互斥责任。
已邀请:

帅驴

赞同来自:

着名的问题。 C++ 互斥锁是OS提供的互斥锁的薄层,并且OS提供的互斥锁通常无效。 他们不在乎 FIFO.

同样硬币的另一侧是,流动通常不是前方,直到它们耗尽临时切割。 结果,流和在这种情况下,最有可能会继续执行并立即接收 mutex.

小明明

赞同来自:

无意中假设流必须同步对同步原语的访问权限。 互斥锁,如下名称,与相互异常相关联。 它们不旨在控制流程。 如果要发信号通知从另一个线程开始的流,则需要使用旨在为控制流的同步原语,即信号。

奔跑吧少年

赞同来自:

* 流并完成他举行的工作 mutex, 从而
自由 mutex.
•在这个流程之后很快,应该触摸资源,
保护 mutex, 所以他再次阻止他

在现实世界中,程序工作。 任何流程库都没有保证或 OS. 这里 "

不久之后

这个的" 可能意味着很多 OS 和硬件。 如果你这么说的话 2 分钟,那个线程肯定会得到它。 如果你说 200 MS或更少,那么没有承诺,或者它将收到。

内核数量,加载不同 processors/cores/threading 单位,不和谐,切换线程, kernel/用户切换保护,优先级,东部时间的死端检测方案。 al。 产生很大的不同。 只需查看远处的绿色信号,您就无法保证您获得绿色。

如果你想要一条溪流 B 必须获得资源,您可以使用该机制 IPC, 指示流量 B 获得资源。

卫东

赞同来自:

保证 a STD :: Mutex是对共享资源独占访问的可能性。 他唯一的目标是消除比赛的地位,当几条流正试图访问公共资源时。

开发人员 mutex 可以选择有利于当前的流获取 mutex /另一个主题/ 提高性能。 允许接收当前流 mutex 并在不需要切换上下文的情况下向前移动通常是由支持的优选选择选择 profiling/measurements.

作为备选, mutex 可以设计更喜欢另一个 /zeblokirovanny/ 收据流动 /也许是按照的选择选择 FIFO/. 这可能需要流上下文的流程 /在相同或其他处理器核心/, 越来越多 latency/overhead.

NOTE

: FIFO 互斥锁可能以惊人的方式行事。 E.g. 应考虑到溪流的优先事项 FIFO - 因此,收购不会严格 FIFO, 如果所有竞争流都没有相同的优先级。

添加要求 FIFO 根据定义 mutex 限制表演者确保在额定工作负载下的不良性能。 /看上面/

保护对象队列 /std::function/ 通过 mutex 允许您执行连续执行。 有几个线程可以得到 mutex, 放入名为对象和发布的队列 mutex. 可以在一个线程中执行呼叫对象。 /或者如果不需要同步,则会子弹/.

小姐请别说爱

赞同来自:

这里的逻辑非常简单 - 该流不是在互斥锁的基础上涂过的,因为它需要每次操作产生的费用 mutex, 这绝对不是你想要的。 捕获成本 mutex 它足够高,以免强迫计划员寻找其他流开始。

如果您想修复它,您可以随时获取当前流。 您可以使用 std::this_thread::yield// -
http://en.cppreference.com/w/cpp/thread/yield
-还有这个

能够

有机会流动 B take mutex. 但在你做之前,让我告诉你,这是一种非常脆弱的方式,做事并且没有给予任何保证。 作为替代方案,您可以探讨更深的问题:

为什么问题在于流动的事实 B 没有开始 A 发布资源? 您的代码不应依赖于此类逻辑。

考虑使用诸如障碍物的替代流量同步对象 /boost::barrier 或者
http://linux.die.net/man/3/pthread_barrier_wait
/, 如果你真的需要这样的逻辑。

探索您是否真的需要发布 mutex 经过 A 在这个时刻 - 我发现快速阻止和解放的做法 a mutex 不止一次的代码的气味,它通常会非常影响性能。 看看您是否可以将数据提取分组为您可以玩的不可变结构。

雄心勃勃,但尝试在没有互斥锁定的情况下工作,而不是阻止结构和更功能的方法,包括使用多个不可改变的结构。 我经常在更新我的代码中找到一个相当大的成绩来不使用互斥锁 /并且仍然正确地工作 mt/

裸奔

赞同来自:

你来自哪里

知道

:

虽然流动和持有 mutex, 流程试图阻止它。
由于它保持,线程暂停。

你怎么知道线程被暂停? 你怎么知道他不仅仅是在试图抓住城堡之前完成了代码的行,但也没有抓住城堡:

线 B:


x = 17; // is the thread here?
// or here? /'between' lines of code/
mtx.lock//; // or suspended in here?
// how can you tell?


你不能说。 至少在理论上。

因此,为抽象机器采集锁定的顺序 /也就是说,语言/ 没有确定。

要回复问题请先登录注册