【node学习】协程

本文介绍了协程的基本概念及其与进程、线程的区别,并详细解释了协程如何实现函数的分段式执行,以及在实际编程中的优势。通过对比多线程编程模式,展示了协程在简化代码和提高执行效率方面的优点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

协程

要理解generator就必须知道一个概念,那就是协程

1. 基本概念

协程,又成为微线程(coroutine)。

进程(process) vs 线程(thread)

我们都知道在操作系统级别上有两个重要的概念(也是实体):进程(process)和线程(thread),这两个东西是用于操作系统模拟并行的,在单个CPU上,os通过调度算法,让CPU轮流执行线程或者进程,来达到程序的并发执行。

那么协程又是什么?首先要明确的是,协程是编译器级别的,而并非线程和进程一样是操作系统级别的。协程的实现,通过是对某个语言做相应的提议,然后通过后成编译器标准,然后编译厂商来实现该机制。

2. 作用

协程的作用是什么?

简单来说,就是实现函数的分段式执行。就是一个函数的执行可以主动放弃CPU的控制权,先挂起,让其他的函数先执行,然后在返回,从上次执行结束的地方继续执行。

这样看起来很像是多线程轮流执行。但是却有着很大的区别:协程是一个线程执行

  • 因为是一个线程执行,所以不存在线程的切换,而是由程序自身控制,也就不存在所谓的线程切换的开销。

  • 不需要多线程的锁机制。因为只有一个线程,也就不存在同时写变量的冲突。在协程中控制共享资源不加锁,只需要判断状态就好了。这也说明协程的执行效率很高一些。

举个生产者消费者模型基于抢占式多线程编程的实现(伪代码)

// 资源,队列容器
var q = [];

// 消费者进程
loop(); // 循环等待
lock(q); // 加锁
var item = getResourceFrom(q); // 获取资源
unlock(q); // 操作结束,资源解锁
operatingResource(item);
sleep;

// 生成者线程
loop(); // 循环等待
var item = createResource(p); // 生产资源
lock(q); // 加锁
q.push(item); // 写入资源
unlock(q); // 解锁

可以看到,以上的代码中有两个特点

  1. 对资源操作需要进行加锁和解锁的操作。(保证线程安全)

  2. 消费者线程必须通过sleep,让出CPU,用于执行生产者线程使用。

那么如果是协程的编程模式,就简单地多。

var q = [];
var count = 0;

// 消费者
function *consumer() {
    while (true){
       var item = yield producer();
       console.log(item); 
    }
}

// 生产者
function producer() {
    q.push(count++);
}

function main () {
    const consumerGen = consumer();
    // 我们可以通过代码来控制其交替执行

    // 执行到获取item之前,放弃执行权,先执行producer(),
    consumerGen.next();
    // 之后可以获取item,然后再放弃执行权,执行producer,一直循环
    consumerGen.next(q.shift()); // 0
    consumerGen.next(q.shift()); // 1
    consumerGen.next(q.shift()); // 2
    consumerGen.next(q.shift()); // 3
    consumerGen.next(q.shift()); // 4
    consumerGen.next(q.shift()); // 5
}

main();

最后说几句

好久在这上面写博客了,最近一直忙于毕业设计学习node

参考

  1. 协程-廖雪峰

  2. C++ 协程与网络编程

  3. 谈谈协程和C语言的协程

  4. 协程(Coroutine)并不是真正的多线程

  5. 协程(一)原理

<think>嗯,用户之前问了关于Ping使用的端口和服务的问题,现在又转向线程和协程的概念。他们可能刚开始学习计算机科学或者网络相关的知识,现在想进一步了解多任务处理的相关概念。 首先,我需要确定用户对操作系统和并发编程的基础了解程度。线程和协程都是并发编程中的重要概念,但层次不同。用户可能听过这些术语,但不清楚它们之间的区别和适用场景。 用户的问题比较直接,但需要结构清晰的回答。根据之前的回答,用户喜欢分点说明,所以这次也应该保持类似的格式,比如定义、区别、适用场景等。 线程是操作系统调度的基本单位,属于内核层面的概念。而协程是用户态的轻量级线程,由程序控制调度。需要解释这两者的核心区别,比如资源消耗、切换开销、并发能力等。 用户可能关心为什么需要协程,线程有什么不足。比如,线程创建和切换的开销较大,协程更轻量,适合高并发场景。可能需要举例说明,比如网络服务中处理大量连接时,协程的优势。 还要注意用户可能的实际应用场景,比如他们是否在开发高并发的服务器应用,或者进行数据处理等。这样可以帮助用户理解何时选择线程,何时使用协程。 另外,用户可能对协程的实现机制感兴趣,比如在Python中的生成器,或者Go语言的goroutine。需要简要提及不同语言中的协程实现,但避免过于深入,以免让用户感到困惑。 最后,总结两者的对比,帮助用户做出选择。确保回答真实可靠,引用正确的技术术语,同时保持语言通俗易懂,符合用户的中文理解习惯。</think>好的!以下是关于**线程**和**协程**的对比解析: --- ### **1. 线程(Thread)** - **定义** 线程是操作系统调度的最小执行单元,属于**内核级并发**机制。一个进程(如运行中的程序)可以包含多个线程,共享进程的内存空间(如堆、全局变量),但每个线程拥有独立的栈和寄存器状态。 - **特点** - **调度方式**:由操作系统内核调度(抢占式) - **资源开销**:线程创建、切换需内核介入,开销较大(典型线程栈约1MB) - **并发能力**:受限于CPU核心数,多线程并行需硬件支持 - **典型应用**:CPU密集型任务(如数值计算)、需要并行利用多核的场景 - **示例**(Python) ```python import threading def task(): print("线程执行") t = threading.Thread(target=task) t.start() ``` --- ### **2. 协程(Coroutine)** - **定义** 协程是**用户级轻量级线程**,由程序员主动控制调度,属于协作式并发。协程在单线程内通过**协作切换**实现并发,无需内核介入。 - **特点** - **调度方式**:由用户程序主动让出控制权(非抢占式) - **资源开销**:协程切换只需保存少量寄存器,内存占用通常为KB级 - **并发能力**:适合高并发I/O密集型任务(如网络请求),单线程可支撑数万协程 - **典型应用**:Web服务器、异步编程、高并发微服务 - **示例**(Python asyncio) ```python import asyncio async def task(): print("协程执行") await asyncio.sleep(1) # 主动让出控制权 asyncio.run(task()) ``` --- ### **3. 核心区别对比** | **特性** | **线程** | **协程** | |----------------|---------------------------|------------------------------| | **调度主体** | 操作系统内核 | 用户程序(开发者/运行时库) | | **切换开销** | 高(涉及内核态切换) | 极低(仅用户态操作) | | **并发规模** | 数百级别 | 数万甚至百万级别 | | **数据竞争** | 需锁/信号量避免冲突 | 单线程内无竞争(但多线程混合使用时仍需注意) | | **适用场景** | CPU密集型、多核并行 | I/O密集型、高并发请求处理 | --- ### **4. 技术演进与典型实现** - **协程实现模式** - **生成器模式**:Python的`yield`、JavaScript的`Generator` - **异步I/O框架**:Python的`asyncio`、Go的`goroutine`(严格说goroutine是更高级的抽象) - **事件循环**:Node.js的`Event Loop` - **混合使用场景** 现代高并发系统常结合两者: - 多线程处理CPU密集型任务 - 协程处理I/O密集型任务 - 例如:Nginx(多进程+协程)、Go语言(goroutine + 多线程调度器) --- ### **5. 选择建议** - **优先协程**:当需要处理大量I/O操作(如HTTP请求、数据库访问)且追求高吞吐时 - **选择线程**:当任务计算密集且需充分利用多核CPU时 - **混合架构**:使用线程池管理CPU任务 + 协程管理I/O任务(如Python的`concurrent.futures`) 理解这两者的差异,能帮助你更高效地设计并发架构!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值