7.1 协程的概念和应用场景
- 核心概念: 协程(Coroutine)是一种轻量级的线程,可以在执行过程中暂停和恢复,用于实现并发和异步编程。
- 与线程的区别:
- 线程由操作系统调度,协程由程序自身调度。
- 线程切换的开销较大,协程切换的开销较小。
- 线程可以并行执行,协程通常是串行执行。
- 应用场景:
- 异步 I/O: 在等待 I/O 操作完成时,暂停协程,避免阻塞主线程。
- 事件驱动编程: 在事件发生时,恢复相应的协程,处理事件。
- 生成器: 用于生成序列数据,避免一次性生成大量数据。
- 状态机: 用于实现复杂的状态转换逻辑。
- 游戏开发: 用于实现游戏逻辑的并发执行,例如 AI 行为、动画效果等。
- 优势:
- 提高程序的并发性和响应性。
- 降低程序的资源消耗。
- 简化异步编程的复杂性。
7.2 协程的创建和启动
-
coroutine
关键字: 用于定义协程函数。 -
startCoroutine()
函数: 用于启动协程,并返回协程句柄。 -
协程句柄: 用于控制协程的执行,例如暂停、恢复和终止。
-
示例代码:
coroutine myCoroutine() { print("协程开始"); yield(); // 暂停协程 print("协程恢复"); } coroutineHandle handle = startCoroutine(myCoroutine()); print("协程已启动");
7.3 协程的暂停和恢复
-
yield()
函数: 用于暂停协程的执行,并将控制权返回给调用者。 -
resumeCoroutine()
函数: 用于恢复协程的执行,从上次暂停的位置继续执行。 -
示例代码:
coroutine myCoroutine() { print("协程开始"); yield(); print("协程恢复"); yield(); print("协程再次恢复"); } coroutineHandle handle = startCoroutine(myCoroutine()); resumeCoroutine(handle); // 第一次恢复 resumeCoroutine(handle); // 第二次恢复
7.4 协程句柄 (coroutineHandle)
-
核心概念: 协程句柄是一个用于控制协程的对象,可以用于暂停、恢复和终止协程。
-
coroutineHandle
类型: 表示协程句柄的数据类型。 -
startCoroutine()
函数的返回值: 返回一个coroutineHandle
对象。 -
resumeCoroutine()
函数的参数: 接受一个coroutineHandle
对象。 -
示例代码:
coroutine myCoroutine() { print("协程开始"); yield(); print("协程恢复"); } coroutineHandle handle1 = startCoroutine(myCoroutine()); coroutineHandle handle2 = startCoroutine(myCoroutine()); resumeCoroutine(handle1); // 恢复 handle1 对应的协程 resumeCoroutine(handle2); // 恢复 handle2 对应的协程
7.5 协程的生命周期
-
创建: 使用
startCoroutine()
函数创建协程。 -
启动: 协程创建后立即启动,开始执行协程函数。
-
暂停: 使用
yield()
函数暂停协程的执行。 -
恢复: 使用
resumeCoroutine()
函数恢复协程的执行。 -
终止: 协程函数执行完毕或遇到错误时,协程终止。
-
示例代码:
coroutine myCoroutine() { print("协程开始"); yield(); print("协程恢复"); print("协程结束"); } coroutineHandle handle = startCoroutine(myCoroutine()); resumeCoroutine(handle); resumeCoroutine(handle); // 协程已结束,再次恢复无效
7.6 协程的通信
-
共享变量: 协程之间可以通过共享变量进行通信。
-
通道(Channel): 可以使用通道实现协程之间的同步和通信。
-
示例代码(使用共享变量):
global int counter = 0; coroutine increment() { for (int i = 0; i < 5; i++) { counter++; yield(); } } coroutine printCounter() { for (int i = 0; i < 5; i++) { print(counter); yield(); } } coroutineHandle handle1 = startCoroutine(increment()); coroutineHandle handle2 = startCoroutine(printCounter()); for (int i = 0; i < 5; i++) { resumeCoroutine(handle1); resumeCoroutine(handle2); }