gpt4 book ai didi

C++ 线程与可见性问题——常见的工程实践是什么?

转载 作者:太空狗 更新时间:2023-10-29 19:52:22 28 4
gpt4 key购买 nike

从我的研究中,我知道饥饿、死锁、公平和其他并发问题的概念。然而,理论在一定程度上不同于实践,实际的工程任务通常涉及比学术等等更多的细节......

作为一名 C++ 开发人员,我一直在关注线程问题......

假设您有一个共享变量x,它引用程序内存的较大部分。该变量在两个线程 AB 之间共享。

现在,如果我们考虑 AB 线程对 x 的读/写操作,可能同时进行,则有需要同步那些操作,对吗?因此,对 x 的访问需要某种形式的同步,例如可以通过使用互斥锁来实现。

现在让我们考虑另一种情况,其中 x 最初由线程 A 编写,然后传递给线程 B(以某种方式)并且该线程仅读取 x。线程 B 然后生成对 x 的响应,称为 y 并将其传递回线程 A(同样,不知何故)。我的问题是:我应该使用什么同步原语来使这个场景线程安全。我读过原子学,更重要的是,内存栅栏 - 这些是我应该依赖的工具吗?

这不是典型的存在“临界区”的场景。相反,一些数据在线程之间传递,不可能在同一内存位置并发写入。因此,在写入之后,数据应该首先以某种方式“刷新”,以便其他线程在读取之前可以看到它处于有效且一致的状态。文献中怎么称呼,是“能见度”吗?

pthread_once 及其对应的 Boost/std,即 call_once 呢?如果 xy 通过一种“消息队列”在线程之间传递,这是否有帮助,该消息队列通过“一次”功能访问。 AFAIK 它作为一种内存栅栏,但我找不到任何证实。

CPU 缓存及其一致性如何?从工程学的角度来看,我应该知道些什么?这些知识对上述场景或 C++ 开发中常见的任何其他场景有帮助吗?

我知道我可能会混合很多主题,但我想更好地了解什么是常见的工程实践,以便我可以重用已知的模式。

这个问题主要与C++03的情况有关,因为这是我日常工作的环境。由于我的项目主要涉及Linux,所以我可能只会使用pthreads和Boost,包括Boost.Atomic。但我也很感兴趣,如果有关此类问题的任何事情随着 C++11 的出现而发生了变化。

我知道这个问题很抽象,不够精确,但任何输入都可能有用。

最佳答案

you have a shared variable x

那是你出错的地方。如果您使用某种线程安全的消费者-生产者队列移交工作项的所有权,那么线程化会容易得多,并且从程序的其余部分(包括所有业务逻辑)的角度来看,没有任何共享。

消息传递还有助于防止缓存冲突(因为没有真正的共享——除了生产者-消费者队列本身,如果工作单元很大,这对性能的影响微不足道——并将数据组织成消息有助于减少虚假分享)。

当您将问题分解为子问题时,并行性的扩展性最好。小的子问题也更容易推理。

您似乎已经按照这些思路进行了思考,但是不,像原子、互斥和栅栏这样的线程原语对于使用消息传递的应用程序来说不是很好。找到一个真正的队列实现(队列、圆环、Disruptor,它们名称不同但都满足相同的需求)。这些原语将在队列实现中使用,但绝不会被应用程序代码使用。

关于C++ 线程与可见性问题——常见的工程实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26684701/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com