使用GCD实现并发读独占写模型

2024-05-21

我试图了解使用 Grand Central Dispatch (GCD) 实现控制资源访问的并发读独占写模型的正确方法。

假设有一个 NSMutableDictionary 被大量读取并且偶尔更新。确保读取始终与字典状态一致的正确方法是什么?当然,我可以使用队列并序列化对字典的所有读写访问,但这会不必要地序列化应允许同时访问字典的读取。乍一看,在这里使用组听起来很有希望。我可以创建一个“读取”组并将每个读取操作添加到其中。这将允许同时进行读取。然后,当需要进行更新时,我可以将dispatch_notify()或dispatch_wait()作为写入操作的一部分,以确保在允许继续更新之前完成所有读取。但是,如何确保在写操作完成之前不会开始后续的读操作呢?

这是我上面提到的字典的一个例子:
R1:在 0 秒时,需要 5 秒才能完成的读取
R2:在 2 秒处,另一个读取进来,需要 5 秒才能完成
W1:在 4 秒时,写入操作需要访问字典 3 秒
R3:在 6 秒时,另一个读取进来,需要 5 秒才能完成
W2:在 8 秒处,另一个写入操作到来,也需要 3 秒才能完成

理想情况下,上面的结果应该是这样的:
R1 从 0 秒开始,到 5 秒结束
R2 从 2 秒开始,到 7 秒结束
W1 从 7 秒开始,到 10 秒结束
R3 从 10 秒开始,到 15 秒结束
W2 15 秒开始,18 秒结束

注意:即使R3在6秒到来,但也不允许在W1之前开始,因为W1来得更早。

使用 GCD 实现上述内容的最佳方法是什么?


我认为你的想法是正确的。从概念上讲,您想要的是一个私有并发队列,您可以向其中提交“屏障”块,这样屏障块就会等待,直到所有先前提交的块完成执行,然后自行执行所有块。

GCD 尚未(还?)提供开箱即用的此功能,但您可以通过将读/写请求包装在一些附加逻辑中并通过中间串行队列汇集这些请求来模拟它。

当读请求到达串行队列的前面时,dispatch_group_async将实际工作放到全局并发队列上。如果是写请求,您应该dispatch_suspend串行队列,并调用dispatch_group_notify仅在前面的请求执行完毕后才将工作提交到并发队列中。执行此写入请求后,再次恢复队列。

像下面这样的东西可以让你开始(我还没有测试过这个):

dispatch_block_t CreateBlock(dispatch_block_t block, dispatch_group_t group, dispatch_queue_t concurrentQueue) {
    return Block_copy(^{ 
        dispatch_group_async(concurrentQueue, group, block);
    });
}

dispatch_block_t CreateBarrierBlock(dispatch_block_t barrierBlock, dispatch_group_t group, dispatch_queue_t concurrentQueue) {
    return Block_copy(^{
        dispatch_queue_t serialQueue = dispatch_get_current_queue();
        dispatch_suspend(serialQueue);
        dispatch_group_notify(group, concurrentQueue, ^{
            barrierBlock();
            dispatch_resume(serialQueue);
        });
    });
}

使用dispatch_async将这些包装块推送到串行队列上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用GCD实现并发读独占写模型 的相关文章

  • 使用 UItableviewCell 实现 Google 地图

    我正在尝试在 UItableviewCell 组件内实现谷歌地图 我这样做的方法是在原型单元中定义 GMSMapView 然后使用 dequeueReusableCell 方法配置地图单元 但是 我尝试应用的任何更改都会失败 例如添加标记
  • 从xcode上触摸屏的坐标获取ImageView的像素数据?

    单击视图并从视图内的图像获取正确的像素数据似乎存在问题 func handleTap gestureRecognizer UIGestureRecognizer print You tapped at gestureRecognizer l
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数
  • Swift 3:如何访问48字节CFData中matrix_float3x3的值?

    我正在尝试访问内在矩阵answer https stackoverflow com a 48159895 9296667 通过运行下面的命令 我能够得到一个 48 字节的任意对象 https developer apple com docu
  • 如何在 iOS 中通过 Twitter API 获取用户电子邮件地址?

    我尝试了多个 SDK 但无法从任何资源获取电子邮件 ID 我努力了FHSTwitterEngine为此目的 但我没有得到解决方案 FHSTwitterEngine twitterEngine FHSTwitterEngine sharedE
  • 无法从 iOS 中的框架访问 .nib(XIB) 文件

    我已经从现有的代码库中创建了一个框架 并尝试在新的代码库中使用它 这很好用 但是当我尝试访问属于我的框架包的一部分的 nib 文件时 我的应用程序崩溃了 这是我用来访问视图控制器 XIB 文件的代码 testViewController c
  • iOS Safari Mobile 禁用上一个和下一个选择输入

    上周五我发现了关于此问题的类似问题 但似乎无法再次找到它 如果有人能指出我正确的方向 那就太好了 本质上我在一个页面上有多个选择菜单 第一个在加载时填充 第二个在第一个选择时填充 够简单的 但是 在 iOS 设备中 当您点击选择元素时 它会
  • iOS - 如何在 swift 中使用 `NSMutableString`

    我已经看过这段 Objective C 代码 但我很难在 swift 中做同样的事情 NSMutableAttributedString res self richTextEditor attributedText mutableCopy
  • 如何开始复杂级别的跨平台移动应用开发? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么performSegueWithIdentifier在viewDidLoad中不起作用?

    我试图在视图控制器上调用 viewDidLoad 后立即触发故事板转场 Segue 附加了一个标识符 当从链接到按钮或其他控件的方法内部调用时 它可以正常工作 但它在 viewDidLoad 内部不起作用 它只是默默地失败了 viewDid
  • React-native-vision-camera无法访问后面的普通摄像头

    我正在尝试在 iPhone 11 Pro 上使用 普通 相机 我使用反应本机视觉相机 当我运行这段代码时 const devices useCameraDevices const deviceBack devices back consol
  • 如何制作带有 SWIFT 图像的弹出窗口

    我想知道如何制作类似于此示例的弹出窗口 原始窗口充满了按钮 选择这些按钮后将拉出我想要使用的图像 我会简单地创建一个可重用的UIView组件以及作为子视图所需的一切 例如UIImageView为了你的形象 UILabel or a UIBu
  • 如何保护 iOS 应用程序免受任何操作系统攻击(在越狱设备上)

    我希望保护我的应用程序数据 以防任何操作系统攻击或越狱 iOS 设备上的未经授权的访问 在这种情况下 有什么方法可以检测此类威胁并保护应用程序数据 虽然我同意 jrturton 的说法 但如果您有想要保护的关键数据免受流氓应用程序 而不是用
  • 每 24 小时触发一次方法

    我正在尝试每天在给定时间触发一个方法 我尝试了一些方法 但我无法真正使其发挥作用 任何意见 将不胜感激 此外 如果无论应用程序是否打开它都会触发 那就更理想了 这可能吗 UI本地通知 http developer apple com lib
  • ios swift parse:从 3 个类收集数据

    我有这样的结构 User CardSet 带有指向 User objectId 的指针 user 和 col name 带有点 cards 的卡片到 Card Set objectId 和列 name 我想选择所有卡数据 包括当前用户的卡集
  • dyld:无法加载插入的库

    当我尝试运行 UI 和单元测试时 出现异常 dyld 无法加载插入的库 private var containers Bundle Application AutoTestingApp app Frameworks IDEBundleInj
  • 为什么 iOS 启动屏幕很慢?

    我的 iOS 应用程序启动屏幕大约需要 3 5 秒 我有一张将在启动屏幕后加载的地图 我的用户必须等待启动屏幕加载 然后再等待 3 秒才能加载地图 有没有办法最大限度地减少启动屏幕时间 基本上这种延迟意味着you在启动过程中做了一些非常错误
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • 会话重新启动后 AVcapture 会话启动缓慢

    我有一个主视图控制器 它连接到具有 avcapturesession 的第二个视图控制器 我第一次从主视图控制器转向捕获会话控制器 大约需要 50 毫秒 使用 仪器 检查 然后我从捕获会话返回到主视图控制器 然后从主控制器返回到 avcap
  • 更改 iOS7 中 UIAlertView 的字体大小

    我想更改alertView中消息文本和标题文本的字体大小 苹果网站上没有任何文档谈到这一点 但苹果在其子类注释中表示 UIAlertView 类旨在按原样使用 请参考以下链接 https developer apple com librar

随机推荐

  • 如何在 RDLC 报告上添加每个组的行号?

    我如何添加这样的行号 GROUP 1 行号 ID 姓名 年龄 1 231 test 43 2 324 test2 45 3 354 test3 34 GROUP 2 行号 ID 姓名 年龄 1 657 test4 43 2 534 test
  • Android 中的 AES 解密速度慢

    我尝试使用 AES 128 位密钥解密 4 2 MB dcf 文件 但解密需要 33 秒 在函数 cipher doFinal data 上 这正常吗 这是一个代码片段 long start System currentTimeMillis
  • 给定数十亿个 URL,如何确定重复内容 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在一次编程面试中被问到这个问题 我在下面详细描述了这个问题 这是一个开放式问题 给定数十亿个 URL 深层链接 我如何对哪些 URL
  • 如何从基类捕获点击项目(位于模板中)的事件?

    我有一个基础网格
  • “Equals”和“SequenceEqual”之间的区别?

    是否存在以下情况 Equals MyList1 MyList2 MyList1 SequenceEqual MyList2 两者之间有什么区别 Equals obj1 obj2 and obj1 Equals obj2 Thanks Equ
  • 主线程迭代之间的资源锁定(Async/Await)

    假设我有一个带有两个按钮的表单 button1 and button2 和资源对象 r 资源有自己的锁定和解锁代码来处理并发性 任何线程都可以修改资源 When button1单击后 其处理程序会进行一些修改r本身然后调用 Independ
  • Atom——片段不起作用

    以下是我在 snippets cson 文件中编写的两个片段 source python print statement prefix pr body print 1 Hello world source python Argument v
  • 64 位 ASP.NET MVC 应用程序无法运行

    首先 我之前曾设法让我的一个 64 位测试 Web 应用程序在这台机器上运行 当我为这个项目制作原型时 我已经在 32 位环境中工作了几周 意识到我需要将应用程序切换到 64 位 当我这样做 在项目中将目标平台设置为 x64 并重新部署时
  • Mvvm跨本地化:运行时切换

    有没有办法在运行时将当前语言更改为另一种语言 例如 能够在单击按钮时或启动应用程序时进行切换 获取用户语言并进行切换 如何告诉插件在启动时检查用户语言 在此先感谢您的帮助 有没有办法在运行时将当前语言更改为另一种语言 是的 打电话build
  • 如何从 Python 中运行“python setup.py install”?

    我正在尝试创建一个通用的 python 脚本来启动 python 应用程序 并且如果目标系统中缺少任何依赖的 python 模块 我想安装它们 如何从 Python 本身运行相当于命令行命令 python setup py install
  • 如何退出两个嵌套循环? [复制]

    这个问题在这里已经有答案了 我使用 Java 已经有一段时间了 但我对循环的了解还有些欠缺 我知道如何创建 java 中存在的每个循环并跳出循环 然而 我最近思考了这个问题 假设我有两个嵌套循环 我可以只用一个循环来打破这两个循环吗brea
  • Git 工作流程:分叉项目并维护本地修改副本,但保持最新

    我正在尝试找出最佳工作流程 用于维护具有自定义功能的 github 托管项目 moodle 的本地副本 同时保持保持副本最新的能力 告诉我我正在考虑做的事情是否完全疯狂 分叉项目 github com moodle moodle gt gi
  • 将暂停屏幕绘制为播放屏幕上的一层 -LibGdx

    在我的 LibGdx 游戏中 我创建了暂停功能 在玩游戏时 如果我按下暂停按钮 则会显示一个带有恢复按钮的单独屏幕 实际上我想做的是暂停屏幕应该像一层一样出现在游戏屏幕上方 就像下面的游戏截图一样 我只能在我的游戏中使用单独的背景和所有内容
  • 使用“ember-rails”将路由从 Rails 迁移到现有 Rails 应用程序的 Ember

    将 gem ember rails 用于现有的 Rails 应用程序 我正在尝试使用 Ember 路由一个资源 很多人告诉我这段代码应该可以工作 但事实并非如此 我想突破学习曲线并使这项工作成功 但我需要一些帮助 Error Routing
  • ipython 笔记本锚链接直接从外部引用单元格

    我正在为基于笔记本的框架编写文档 当引用演示笔记本中的重要单元格时 我可以使用某种锚点来指向特定单元格吗 例如 如果我的演示笔记本位于 127 0 0 1 mydemo 是否可以通过某些锚标记 如 127 0 0 1 mydemo In10
  • Objective-C 中 typedef 枚举语句在哪里?

    我担心的一个基本问题 以下代码有效 并且 typedef 枚举被识别 但我收到一条警告消息 空声明中无用的存储类说明符 我在这里做错了什么吗 这是放置 typedef 枚举的最佳位置吗 import
  • WordPress 安装中发现的恶意 PHP 代码有什么作用?

    我能够解码在一些 WordPress 文件中找到的以下 PHP 脚本 只是出于好奇 有人可以告诉我这段代码实际上是做什么的吗 看起来它已经以某种方式复制到同一服务器上的其他 WordPress 安装中
  • 使用 Python 在 Django 中将 Unix 时间戳转换为人类格式

    我想将字符串中的 unix 时间戳 例如 1277722499 82 转换为更人性化的格式 hh mm ss 或类似格式 有没有一种简单的方法可以在 python 中为 django 应用程序执行此操作 这是在模板之外 在我想要执行此操作的
  • 如何在 JSFiddle 中链接外部 json 文件?

    我有一个很长的 json 文件country json name WORLD population 6916183000 name More developed regions population 1240935000 name Less
  • 使用GCD实现并发读独占写模型

    我试图了解使用 Grand Central Dispatch GCD 实现控制资源访问的并发读独占写模型的正确方法 假设有一个 NSMutableDictionary 被大量读取并且偶尔更新 确保读取始终与字典状态一致的正确方法是什么 当然