过去两天我一直在阅读《编程艺术》第一卷。
有一个关于子程序和协程的主题。
我很困惑。我不明白书上说协程是在 main() 之后初始化的,这与子例程不同。此外,被调用的协程成为调用协程的子例程。
我尝试研究之前在这里提出的问题,在相同的上下文中我也了解了函数和线程的概念。
本书给出了一个使用 MIX 计算机模型的协程示例。
我可以使用有关当今高级语言上下文中的协程和其他术语的示例来获得任何简单的伪代码吗?
那么,一个相关的问题:如何区分子例程、协程、函数和线程?
在我们收到真正了解的人的帖子之前,这是我对这个问题的理解,FWIW。
子例程和函数本质上是同一件事,但有一个区别:函数返回某种值(通常通过堆栈或 CPU 寄存器),而子例程则不然。无论是子例程还是函数,它都是一组可执行代码,只有一个入口点。协同例程也是一块可执行代码,并且就像子例程一样,它有一个入口点。然而,它也有一个或多个重新进入点。稍后会详细介绍这一点。
在讨论线程之前,让我们回顾一下:计算机程序(也称为进程)通常将其内存分配组织为代码空间、堆和堆栈。代码空间存储其可执行代码的一个或多个块。堆栈存储子例程、函数和协同例程(以及其他内容)的参数、自动变量和返回地址。堆是进程可以出于任何目的使用的开放内存空间。除了这些内存空间之外,还有 CPU 寄存器,每个寄存器都存储一组位。这些位可以是整数值、内存地址、一堆状态标志或其他任何东西。大多数程序员不需要对它们了解太多,但它们确实存在并且对于 CPU 的运行至关重要。也许值得了解的是程序计数器、堆栈指针和状态寄存器,但我们不打算在这里讨论它们。
线程是单个逻辑执行流。在原始计算系统中,一个进程只有一个线程可用。在现代计算系统中,进程由一个或多个线程组成。每个线程都有自己的堆栈和一组 CPU 寄存器(这通常在物理上是不可能的,但在逻辑上是虚拟的 - 我们将在这里跳过这个细节)。然而,虽然进程的每个线程都有自己的堆栈和寄存器,但它们都将共享相同的堆和代码空间。它们也(大概)同时运行;这在多核 CPU 中确实可以发生。因此程序的两个或多个部分可以同时运行。
回到协同例程:如前所述,它有一个或多个重入点。重进入点意味着协同例程可以允许其自身之外的某些其他代码块具有一些执行时间,然后在将来的某个时间让执行时间恢复回到其自己的代码块内。这意味着每当执行产生到外部代码块然后返回到协同例程的执行时,协同例程的参数和自动变量都会被保留(并在需要时恢复)。协同例程并不是在每种编程语言中都直接实现的,尽管它在许多汇编语言中很常见。无论如何,都可以从概念上实现协同例程。有一篇关于协同例程的好文章,位于http://en.wikipedia.org/wiki/Coroutine http://en.wikipedia.org/wiki/Coroutine.
在我看来,实现协同例程设计模式有两个主要动机:(1)克服单线程进程的局限性; (2)希望获得更好的计算性能。动机 (1) 很容易理解何时进程必须同时处理许多事情,而单个线程是必须的。动机(2)可能不太容易理解,因为它与系统硬件、编译器设计和语言设计的许多细节相关。我只能想象,通过减少堆栈操作、避免在子例程中重做初始化或减轻维护多线程进程的一些开销,可能会减少计算量。
HTH
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)