【问题标题】:How to implement Coroutines on iOS如何在 iOS 上实现协程
【发布时间】:2012-10-29 08:20:35
【问题描述】:

我正在将一个 C++ 项目移植到 iOS,以便在 iPhone 和 iPad 上使用。这个项目广泛使用了 Boost.Coroutine 库。 Boost.Coroutine 没有针对 iPhone 的 ARMv6/ARMv7 指令集的实现。

  • 还有其他可以在 iOS 上运行的协程库吗?

  • 如果没有,是否可以在 ARM 上编写协程行为?我可以看到一些潜在的方法来做到这一点:

    • 直接编写汇编指令来执行堆栈操作。我不太精通汇编,我担心 ARM 架构可能不包含复制和粘贴堆栈或手动移动堆栈指针所需的指令。
    • 使用类似于 pthread 或 Win32 纤程的东西编写协程。我不确定是否有类似的东西可以在 iOS 上使用。
    • 在线程之上实现协程,甚至可能是 Boost.Coroutine 本身。这似乎最有可能奏效,但肯定会有性能缺陷。

注意:Unity 在 iOS 上支持 C# 中的协程;我不确定这是否仅限于典型协程行为的一小部分。如果没有,这是否意味着 Unity 有解决方案?

【问题讨论】:

  • 你能谈谈你想要协程的具体模式吗?除了一个简单的答案之外,如果能够说出诸如“很难做 Y 的原因是正常模式是 X”之类的话,这将是有帮助的。
  • 协程通常是个坏主意——穷人的多任务处理。您可以使用 iOS 调度队列完成大部分相同的功能。 (请记住,弄乱调用堆栈是非常危险的。)
  • @Hot Licks 协程非常有用,可以在语言中使用它们(或更强大的功能,如延续),而且它们不是穷人的多任务处理。以单线程生产者/消费者为例——它可以用协程自然地表达,相同的多线程版本将需要锁。状态机是其他常见的例子。如果协程是个坏主意,为什么许多现代语言都内置了对它们的支持?为什么人们在没有这种支持的情况下实现它们(从 C 到 C#)?调度队列很好,但在这里无关紧要。
  • 一些语言,比如那些实现“延续”的语言需要类似于协程的东西,但大多数语言不需要。至于生产者/消费者,让我向您保证,在现代操作系统上,协程版本将比多线程版本复杂得多(并且几乎肯定需要锁定以防止来自操作系统的破坏性干扰)。我曾经开始在裸 PALM IV 微控制器上实现协程方案,但最终发现非抢占式任务方案更清洁。这是 IBM 5100 的经典生产者/消费者磁带复制实用程序。
  • @Tommy Coroutines 主要在这个项目中用于 RPC 库。为了从原始项目中提取持续的修复和改进,我希望我的解决方案尽可能与源代码实现相似。即,如果我必须重写他们的 RPC 库以不使用协程,我会的,但我想先彻底研究在 iOS 上实现协程的选项。

标签: ios arm coroutine


【解决方案1】:

您几乎肯定不想编写汇编指令来执行堆栈操作。 iOS 已经在其第三版 ARM 指令集上,从 ARMv6 到 ARMv7 再到 ARMv7s。从 iPhone 5 开始,Apple 进一步增加了人为障碍,即您不得提交带有同样支持 iPhone 5 完整屏幕的 ARMv6 分支的应用程序。我确信 Apple 的动机是确保它可以在未来某个时候过渡到没有 ARMv6 兼容模式的处理器,但对于我们开发人员来说,这显然意味着不要过于依赖特定的指令集。

剩下的就是线程。 iOS 拥有一整套完善的线程机制,而 pthread 可以公开相关的子集。 Grand Central Dispatch 往往是现在用来确保不同任务可以同时发生的正常解决方案,因此吞下了大部分 Internet 文档,但仍然保留了较低级别的解决方案。

明显的小例子,使用NSConditionLock

- (void)methodOnThread1
{
    while(1)
    {
        [conditionLock lockWhenCondition:kMoreInputAvailable];

        // process whatever is currently in the common access pool

        [conditionLock unlockWithCondition:kWaitingForInput];
    }
}

- (void)methodOnThread2
{
    while(1)
    {
         // do whatever is necessary to produce more input,
         // creating it locally and taking as long as it takes


        [conditionLock lockWhenCondition:kWaitingForInput];

        // push input to common access pool, by whatever means

        [conditionLock unlockWithCondition:kMoreInputAvailable];
    }
}

【讨论】:

    【解决方案2】:

    boost.coroutine(来自 Oliver Kowalke;上个月从 boost 社区评论)使用支持 ARMv6(ARM Cortext Ax)的 boost.context

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 1970-01-01
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多