C/C++中的协程

传送门 ==>> 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
# 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。

1 为什么需要协程?

要读取文件并在读取一些有意义的数据时对其进行解析, 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.

2 如何在 C 中实现协程?

The challenge is to have coroutines in C language which is itself a stack-based language,即在对 C 语言中的函数调用的每次响应中,都有一个正在初始化的堆栈,该堆栈跟踪其所有变量和常量,并在函数调用时被销毁结束。

  • 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 */
}

我们需要做两件事:

  1. 将控制恢复到上一个状态
  2. Make data persist through calls

上述这两个问题都应该通过使用静态变量来解决。但是如何记住状态并返回到与之前相同的执行状态,即返回或循环之后的代码行。我们可以使用 GOTO 语句,一般不推荐。关于在c语言实现协程,请看如下代码的实现,

  • C++
  • C
// C++ program to demonstrate how coroutines
// can be implemented in C++.
#include <iostream>
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 函数,它也是基于协程的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

糖果Autosar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值