传送门 ==>> AutoSAR实战系列300讲「糖果Autosar」总目录
协程是通用的control structures,其中流控制在两个不同的例程之间协同传递而不会返回。
如果您使用过 Python 或 C#,您可能知道有一个名为yield的关键字,它允许a loop back and forth between the caller and the called function until the caller is not done with the function or the function terminates because of some logic it is given.
示例 是使用yield的Python3 代码。
# Python program to generate numbers in a
# range using yield
def rangeN(a, b):
i = a
while (i < b):
yield i
i += 1 # Next execution resumes
# from this point
for i in rangeN(1, 5):
print(i)
输出
1
2
3
4
这段代码演示了 yield 的工作原理,并简要介绍了 how the control is changed between the caller and callee。
要读取文件并在读取一些有意义的数据时对其进行解析, you can either read step by step at each line, which is fine。您也可以将整个内容加载到内存中【对于大型文本案例(例如 Microsoft Word 等文本编辑器)不建议这样做。 】or in modern systems just use Pipes,
在 The Art of Computer Programming 中,Donald Knuth 提出了解决这类问题的方法。他的回答是完全抛弃堆栈概念。Stop thinking of one process as the caller and the other as the callee,并开始将它们视为合作平等。所以我们现在可以尝试看看如何在 C 中实现同样的效果。
function read():
/* reads the content in the desired number
of steps and returns back control to parser
but saves its own state of function. */
function parse():
a = read()
while (a)
{
// do something
a = read()
}
实际上,这个结构看起来非常类似于 C 的调用者-被调用者结构。 But what we require here is that the reader must remember its state. It must remember where it was last time when it did the job and should also be re-settable.
The challenge is to have coroutines in C language which is itself a stack-based language,即在对 C 语言中的函数调用的每次响应中,都有一个正在初始化的堆栈,该堆栈跟踪其所有变量和常量,并在函数调用时被销毁结束。
int read(void)
{
int i;
for (i = 0; i < 10; i++)
return i; /* Well on the first run itself
the function will be destroyed */
}
我们需要做两件事:
上述这两个问题都应该通过使用静态变量来解决。但是如何记住状态并返回到与之前相同的执行状态,即返回或循环之后的代码行。我们可以使用 GOTO 语句,一般不推荐。关于在c语言实现协程,请看如下代码的实现,
// C++ program to demonstrate how coroutines
// can be implemented in C++.
#include
using namespace std;
int range(int a, int b)
{
static long long int i;
static int state = 0;
switch (state)
{
case 0: /* start of function */
state = 1;
for (i = a; i < b; i++)
{
return i;
/* Returns control */
case 1:
cout << "control at range"
<< endl; /* resume control straight
after the return */
}
}
state = 0;
return 0;
}
// Driver code
int main()
{
int i; // For really large numbers
for (; i = range(1, 5);)
cout << "control at main :" << i << endl;
return 0;
}
输出
control at main :1
control at range
control at main :2
control at range
control at main :3
control at range
control at main :4
control at range
We can now essentially have multiple return statements inside the for loop and each time we return to a different state of execution if it’s programmed to do so。这个实现只模仿了Python 的 range 函数,它也是基于协程的。