- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我觉得这可能是一种非常普遍和常见的情况,存在众所周知的无锁解决方案。
简而言之,我希望有像读者/作者锁这样的方法,但这不需要读者获取锁,因此可以获得更好的平均性能。
相反,读者需要一些原子操作(128 位 CAS),而编写者需要互斥。我有数据结构的两个拷贝,一个用于正常成功查询的只读拷贝,以及一个在互斥保护下更新的相同拷贝。将数据插入可写拷贝后,我们将其设为新的可读拷贝。旧的可读拷贝然后依次插入,一旦所有挂起的读取器都完成了读取,并且写入器旋转剩余的读取器数量直到其为零,然后依次修改它,最后释放互斥锁。
或类似的东西。
任何沿着这些路线的东西存在吗?
最佳答案
如果您的数据适合 64 位值,大多数系统可以廉价地以原子方式读取/写入,因此只需使用 std::atomic<my_struct>
.
对于较小和/或不常写入的数据 ,有几种方法可以让读者真正对共享数据只读,而不必对共享计数器或任何东西进行任何原子 RMW 操作。这允许读取端扩展到多个线程,而无需读取器相互竞争(与 x86 上使用 lock cmpxchg16b
或采用 RWlock 的 128 位原子读取不同)。
理想情况下只是通过 atomic<T*>
额外的间接级别指针(RCU),或者只是一个额外的负载+比较和分支(SeqLock);在读取端没有比 acq/rel 或其他任何东西更强的原子 RMW 或内存屏障。
这适用于许多线程非常频繁地读取的数据,例如由定时器中断更新但到处读取的时间戳。或者一个通常永远不会改变的配置设置。
如果您的数据更大和/或更频繁地更改,其他答案中建议的策略之一 要求读者仍然对某事采取 RWlock 或以原子方式递增计数器将更合适。这不会完美扩展,因为每个读取器仍然需要获得包含锁或计数器的共享缓存行的独占所有权,以便它可以修改它,但没有免费午餐这样的东西。
区域控制单元
听起来像 您已经完成了 RCU 的发明 (Read Copy Update) 在其中更新指向新版本的指针。
但是请记住,无锁读取器在加载指针后可能会停止,因此您会遇到释放问题。这是 RCU 的难点。在内核中,它可以通过设置同步点来解决,在那里你知道没有比某个时间 t 更旧的读者,因此可以释放旧版本。有一些用户空间实现。 https://en.wikipedia.org/wiki/Read-copy-update和 https://lwn.net/Articles/262464/ .
对于 RCU,更改的频率越低,您可以证明复制的数据结构就越大。 例如如果只有管理员以交互方式更改它,即使是中等大小的树也是可行的,而读者在数十个内核上运行,所有内核都在并行检查某些内容。例如内核配置设置是 RCU 在 Linux 中很棒的一件事。
序列锁
如果您的数据很小(例如 32 位机器上的 64 位时间戳),另一个不错的选择是 SeqLock。读取器在将数据非原子复制到私有(private)缓冲区之前/之后检查序列计数器。如果序列计数器匹配,我们就知道没有撕裂。 (作家用单独的互斥体相互排斥)。 Implementing 64 bit atomic counter with 32 bit atomics/how to implement a seqlock lock using c++11 atomic library .
在 C++ 中编写一些可以有效编译为可能会撕裂的非原子拷贝的东西有点小技巧,因为不可避免地会出现数据竞争 UB。 (除非您将 std::atomic<long>
和 mo_relaxed
分别用于每个块,但是这样您就无法使用 movdqu
或其他东西一次复制 16 个字节。)
SeqLock 使读取器在每次读取时都复制整个内容(或者理想情况下只是将其加载到寄存器中),因此它仅适用于小型结构或 128 位整数或其他内容。 但是对于少于 64 字节的数据,它可以相当好,比让读者使用 lock cmpxchg16b
更好。对于 128 位数据,如果您有很多读者并且很少写入。
但是,它不是无锁的:在修改 SeqLock 时休眠的写入器可能会使读取器无限期地重试。对于一个小的 SeqLock,窗口很小,很明显,您希望在进行第一次序列计数器更新之前准备好所有数据,以最大限度地减少中断在更新过程中暂停编写器的机会。
最好的情况是只有 1 个编写器,因此它不必进行任何锁定;它知道没有其他东西会修改序列计数器。
关于c++ - 读者/作者锁...没有读者锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61237650/
我的英语很差,抱歉 这是我的结构: bookstore ---author(app1) ---book(app2) 或者在代码中: from django.db import models from
我有以下脚本从C:驱动器中检索特定文件类型,并将特定文件属性输出到定界的CSV文件。我还希望能够检索文件所有者和作者。很感谢任何形式的帮助。 # PowerShell script to list t
我们厌倦了掉毛。所以我们要使用 black在我们的项目中。不幸的是,它几乎改变了我们项目中的所有其他行,这会使我们丢失大部分作者信息。我们使用 annotate在 pycharm 或 git blam
我在我的asp.net网站中嵌入了java applet来进行数字签名,它在本地主机上工作,但是当发布它时,java applet在浏览器上运行但是未定义在java小程序上调用函数的java脚本代码
我无法找出一种有效的方法来建立表之间的关系。我想拥有一个包含书籍,作者,出版商和注册用户的数据库,并拥有他们的书架(阅读,当前阅读,想要阅读(或计划阅读))。我希望用户能够选择他们已经阅读,想要阅读或
我已经将我的 Git 作者作者姓名从“名尾 ”到“名尾 ” 这两个电子邮件地址与不同的 Github 帐户相关联,我正在将我所有的个人项目迁移到第二个。 我的问题是,我过去在某些私有(private)
我正在使用 svn2git 从现有的 SVN 存储库创建 Git 存储库。我把它全部下载了(所有 10 多个分支、10 多个标签、>4000 次提交)并在 Git 存储库中。现在,不幸的是,所有的作者
问题: 在 HTML 中,您可以使用 author 元标记(或 DC creator)来指示某人是信息(即内容)的作者。但是,我希望能够在元标记中将自己标记为 Web 应用程序开发人员。 大多数人(在
我确信在 git 中有一种方法可以做到这一点,但我的搜索结果是空的。有没有一种简单的方法可以从一次提交中获取消息、提交作者、提交日期和其他信息,并使用这些数据修改第二次提交,而无需复制实际的提交内容?
我已经设置了自己的私有(private) git 服务器,并且有一个 5 人的团队。我已经设置了他们的所有用户帐户,但是我如何防止由随机的奇怪帐户完成对远程的提交。因为我的一些团队也使用 github
我正在阅读这篇文章“http://lethain.com/introduction-to-architecting-systems-for-scale/”。最后,作者提到了平台层。我不明白这一层的范围
我需要在 Mac 上更改 PDF 文件的作者。我曾尝试使用 grep 和 sed 来完成此操作,但没有成功。 如果我在 Preview.app 中打开一个 PDF 文件并转到“工具”>“显示检查器”,
我正在运行此查询。它在 DBpedia ( http://dbpedia.org/sparql ) 上运行良好,但在我的 Java 代码中不起作用: PREFIX res: PREFIX dbped
我有一个用 C 语言模拟读者-作者问题的简单程序。要求用户输入作者数和读者数。然后创建随机数的编写器 - 线程和读取器 - 线程。项目的写入由全局变量 itemsCount 模拟 - 它代表新插入项目
我尝试在 wordpress 中设置一个作者页面。但是所有的作者页面都被重定向到主页。我用谷歌搜索,他们建议禁用插件,然后检查作者页面。我试了一下,发现 Yoast wordpress SEO plu
所以我从 SQL 背景转向 NoSQL。所以我知道我应该在这里“非规范化”。所以基本上我对我必须做的事情有一个简化的想法; 用户这些文件包含身份验证信息,可能是付款方式、用户名和各种详细信息 帖子这些
所以我已经成功地以 domenic 的身份提交了一个 GitHub 项目和 Domenic Denicola .这很烦人,尤其是对于生成摘要。 我知道 how to change the auth
在 PhpStorm 中,我很难在项目设置中设置默认的 git 作者: 我使用“Action finder”并搜索了设置,但我没有找到这个选项。 有谁知道我可以在哪里更改这个值,这样我就不必在每次提交
我一直在尝试使用 php5-ffmpeg 扩展来获取远程 mp3(和其他格式)元数据。 尽管我总是缺少标题、作者、评论、艺术家详细信息,但它正在工作。 我一直在网上搜索答案,但没有找到任何解决方案。
通常,将一些带有作者,版本和许可证信息的行添加到源文件的顶部被认为是一种好习惯。例如,Gnu GPL v3建议添加 Copyright (C) This program is free sof
我是一名优秀的程序员,十分优秀!