Apple doc的GCD生产者-消费者解决方案错误?

2024-06-28

在 Apple 并发编程指南的“从线程迁移”部分中,有
改变生产者-消费者实施 http://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ThreadMigration/ThreadMigration.html#//apple_ref/doc/uid/TP40008091-CH105-SW7,它声称可以使用 GCD 简化典型的多步 pthread 互斥 + 条件变量实现。

使用调度队列,可以简化生产者和消费者 实现到单个调用中:

dispatch_async(queue, ^{
  // Process a work item.
});

当生产者有工作要做时,它所要做的就是将该工作添加到队列中并让队列处理该项目。

生产者-消费者问题也称为有界缓冲区问题,但上面没有提到缓冲区、其边界或消费者,更不用说阻塞生产者和消费者以避免过度/不足运行。

这怎么可能是一个有效的解决方案呢?


在该 Apple 文档中描述的解决方案中:

  1. 没有缓冲区,因为不需要缓冲区;
  2. 系统负载是有界的;
  3. 消费者是任务。

假设您有多个生产者和消费者,生产者将数据放置在共享缓冲区中,消费者从该共享缓冲区读取数据。信号量或监视器用于同步对共享缓冲区的访问,并且缓冲区大小是固定的,以便根据消耗的速率限制正在生成的数据量,从而限制生产者。

在 Grand Central Dispatch 下,消费者是调度到队列的任务。由于任务是 Objective-C 块,因此生产者不需要缓冲区来告诉消费者它应该处理的数据:Objective-C 块会自动捕获它们引用的对象。

例如:

// Producer implementation
while (…) {
    id dataProducedByTheProducer;

    // Produce data and place it in dataProducedByTheProducer
    dataProducedByTheProducer = …;

    // Dispatch a new consumer task
    dispatch_async(queue, ^{
        // This task, which is an Objective-C block, is a consumer.
        //
        // Do something with dataProducedByTheProducer, which is
        // the data that would otherwise be placed in the shared
        // buffer of a traditional, semaphore-based producer-consumer
        // implementation.
        //
        // Note that an Objective-C block automatically keeps a
        // strong reference to any Objective-C object referenced
        // inside of it, and the block releases said object when
        // the block itself is released.

        NSString *s = [dataProducedByTheProducer …];
    });
}

生产者可以放置与其生产的数据一样多的消费者任务。然而,这并不意味着 GCD 将以相同的速度触发消费者任务。 GCD使用操作系统信息来根据当前系统负载来控制执行的任务量。生产者本身不会受到限制,并且在大多数情况下,由于 GCD 固有的负载平衡,因此不必受到限制。

如果确实需要限制生产者,一种解决方案是拥有一个可以调度的主机n生产者任务,并让每个消费者通知主机(通过消费者完成其工作后调度的任务)它已经结束,在这种情况下,主机将调度另一个生产者任务。或者,消费者本身可以在完成后调度生产者任务。

具体回答您所解决的问题:

生产者-消费者问题也称为有界缓冲区问题,但上面没有提到缓冲区

不需要共享缓冲区,因为消费者是 Objective-C 块,它会自动捕获它们引用的数据。

它的界限

GCD根据当前系统负载限制调度任务的数量。

或消费者

消费者是调度到 GCD 队列的任务。

更不用说为了避免超载/欠载而阻塞生产者和消费者了

由于没有共享缓冲区,因此不需要阻塞。由于每个消费者都是一个 Objective-C 块,通过 Objective-C 块上下文捕获机制捕获生成的数据,因此消费者和数据之间存在一对一的关系。

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

Apple doc的GCD生产者-消费者解决方案错误? 的相关文章

随机推荐

  • 文件上传进度条[重复]

    这个问题在这里已经有答案了 可能的重复 PHP 上传进度条 https stackoverflow com questions 849237 upload progress bar in php 任何人都可以建议一种在上传文件时包含文件上传
  • XMLHttpRequest.send 因相对路径而失败

    我在某些可能可以补救的事情上遇到了困难 我正在开发一个没有服务器的网站 这样做时 我在尝试通过 XMLHttpRequest 访问文件时遇到了问题 正如您在示例代码片段中看到的 我创建了变量 使用所需文件的相对路径打开它 然后使用发送函数
  • 如何在烧瓶模板中模拟“current_user”?

    我想嘲笑flask login s current user在模板渲染下 该函数返回当前登录的用户 现在我正在嘲笑AnnonymousUserMixin from flask login如果用户未经过身份验证 则默认返回该值 但这会导致各种
  • 一对多关系:使用 JPA 2.0 更新已删除的子项

    我有双向一对多关系 0 or 1 client 0 个或多个列表产品订单 应在两个实体上设置或取消设置该关系 在客户端 我想设置分配给客户端的产品订单列表 然后应将客户端设置 取消设置为自动选择的订单 在产品订单方面 我想设置分配订单的客户
  • 在 ConEMU 中显示 git 分支

    有没有办法在 ConEmu 中以视觉方式 背景或类似 在 git 中显示分支 Git 分支可以在普通的 cmd 或 Far Manager 提示符中可见 所有魔法都是通过特殊的 ANSI 序列完成的 必须选中 Inject ConEmuHk
  • 获取当前 IP 地址 Xamarin.Forms(跨平台)

    如何获取 Xamarin Forms 跨平台 的当前 IP 地址 WifiManager 我无法使用并且 WifiManager 不能包含吗 public string MyIp foreach IPAddress adress in Dn
  • 如何在UIViewController中设置parentViewController?

    UIViewController 的parentViewController 属性是只读的 但我正在嵌套自定义视图控制器并希望使用此属性 但是 由于它是只读的 并且我没有找到其他方法来设置此属性 我的问题是 如何do我设置的 显然 UINa
  • 我可以在我的应用程序中使用 Whatsapp 发送消息吗

    我想在我的应用程序中使用 Whatsapp 向其他手机发送消息 我在 Github 上看到过这个用于 Whatsapp 的公共 API here https github com venomous0x WhatsAPI 但我没有找到 iOS
  • 这是服务的实际用途吗?

    我需要运行一个在后台处理钩子的应用程序 问题是我必须以管理员身份在系统启动时自动启动它 我尝试使用 Windows 任务计划程序 但在某些系统上它不会以管理员身份启动程序 这会导致奇怪的行为 我从未编写过 Windows 服务 但这是否是创
  • 在 heatmap.2 中将行标签设置为斜体

    我正在尝试使用 R 函数将行标签设置为斜体heatmap 2 没有默认选项 我无法通过设置找到解决方法par font 3 例如 如何将行标签设置为斜体heatmap 2 set seed 123 data matrix sample 10
  • 有没有办法让两张纸保持同步?

    无法仅共享 Google 文档中的一张电子表格 因此 您必须共享整个电子表格 因此 我正在考虑编写一个脚本来同步两个工作表 每个工作表位于不同的电子表格中 我想使用一个函数来获取行作为数组来做到这一点 有更好的策略来做到这一点吗 实现此目的
  • 响应式图像对齐中心 bootstrap 3

    我使用 Bootstrap 3 制作目录 当在平板电脑上显示时 产品图像看起来很难看 因为它们的尺寸较小 500x500 并且在浏览器中的宽度为 767 像素 我想将图像放在屏幕中央 但由于某种原因我不能 谁来帮忙解决问题 有 center
  • 从辅助类将输出写入控制台

    我有一个运行帮助程序类的控制台命令 我想用以下命令编写输出 this gt info 从助手类到控制台 我的代码如下所示 App Http Console Commands SomeCommand php function handle H
  • 将 CSS 应用于括号(圆括号)中的段落中的单词

    各位 情况是这样的 中的话 span 元素来自资源键 括号内的 CSS 需要略有不同 例如 span Hello this a wonderful resource I mean it span 现在的要求是 我的意思是 应该比其他单词的字
  • 使用 SQL 函数在 ActiveRecord 中进行插入/更新

    我想在我的 Rails 应用程序中存储 IP 地址 v4 和 v6 我已经安装了MySQL 的扩展 http labs watchmouse com 2009 10 extending mysql 5 with ipv6 functions
  • 声明日期,然后添加下一个工作日

    我没有得到我需要的结果 我想做的就是声明我的日期 然后添加下一个工作日 IE CASHDATE 1 这有效 但我需要下一个工作日是 5 号 DECLARE CASHDATE DATETIME SET CASHDATE 2016 12 02
  • Shutil.copytree 没有文件

    我正在尝试使用shutil copytree shutil copytree SOURCE DIR TARGET DIR ignore None 此副本也文件在文件夹中 我只需要复制没有任何文件的文件夹 怎么做 您可以通过提供 忽略 功能来
  • 如何使用 Javascript Promise 按顺序执行 AJAX 调用

    我正在循环访问地图 我想使用每个地图值作为参数进行单独的 AJAX 调用 以获取一些数据并记录它 见下文 这是可行的 但我想让 AJAX 调用按照地图的顺序进行 因为每次调用都是异步的 所以看来我应该使用 Promise 来实现按顺序执行
  • 导航控制器工具栏不显示 UIBarButtonItem

    我在 Xcode 6 2 的属性检查器中使用 显示工具栏 复选框在导航控制器上添加 或显示 工具栏 Because 与导航控制器关联的自定义工具栏 只读 我在用着self navigationController setToolbarIte
  • Apple doc的GCD生产者-消费者解决方案错误?

    在 Apple 并发编程指南的 从线程迁移 部分中 有 改变生产者 消费者实施 http developer apple com library ios documentation General Conceptual Concurrenc