python协程和线程_线程和协程之间的区别

线程和协程之间的区别很大,甚至大过进程和线程之间的区别。线程建立在进程之上,协程建立在线程之上。那么协程是什么呢?

协程是一段计算机程序,它一般是一个协作类型的子程序,执行时允许暂停和恢复。协程非常适合实现熟知的程序,例如协作任务,异常,事件循环,迭代器,无限列表和管道。

协程与我们熟知的函数不同(函数也是一段计算机程序)。函数总是一个入口,一次返回,调用顺序明确,但是协程的调用可以中断,然后执行其它程序,在适当的时候再返回来继续执行,可以实现多次返回。

以异常为例。在操作系统中或者其它语言实现中,例如Java,Python等,异常函数被系统全局注册,当一个函数在执行过程中出现异常,系统捕获到异常后,会直接把执行流程跳转到异常函数处执行异常函数,然后也可以跳回异常点继续执行余下的程序。

Python使用yield实现协程。实现原理主要是利用了生成器函数对象是在堆中被创建的,如下图所示:

9759da197e3fb8f7f75ac2946c5fe648.png

线程栈中的局部变量G1,G2,和G3分别引用了堆中的生成器对象。只要这种引用存在,Python虚拟机就不会回收到堆中的生成器。假设有这样一种执行路径:生成器G1放弃执行权,G2代码执行,然后G3,最后回到G1继续执行。此时G1可以在中断点继续执行余下程序,并且执行的上下文跟中断之前是一模一样的。这种执行程序的方式可以类别进程调度,但是跟进程调度又有着巨大的区别。首先,G1,G2和G3一直在同一个线程下执行,三者一通操作之后,该线程甚至可以一直没有被操作系统调度。

这种执行方式看起来好像平平无奇,但是在适合的场景下使用可以发挥出巨大的威力。

为应对Web高并发场景,各大平台主流的解决方案是使用多线程。对每个请求生成一个线程来处理,虽然线程创建占用资源少,但是不要忘记,如果使用到内核线程,那么内核会创建很多线程,这必然会占用宝贵的内核资源。另外,线程切换也会消耗一部分CPU资源,如果线程太多,那么可能部分CPU运算全部消耗在线程调度上。所以,Java网络编程新增了NIO模块,使用异步加线程池的方式实现高并发。

在Python中,使用协程正好可以解决这种IO密集型场景。例如,如果有1万个请求,那么可以生成1万个协程来处理。系统只需要在堆中生成1万个生成器对象即可,并且没有调度带来的消耗。

听起来很美,实际协程的使用是有限制的。协程中的IO操作必须是非阻塞的,如果调用阻塞接口,那么操作系统一旦感知,必然会发生线程调度,把当前线程换出CPU的runqueue队列。另外,Python单个线程的性能实在太感人,所以如果想充分发挥协程的威力,最好的方式是多进程加协程的组合。

怎么在Python中使用协程?可以自己实现,也可以使用第三方库,如eventlet等。

来个小例子:

import time

def consumer():

while True:

x = yield

print 'consume value:%s ' % x

time.sleep(1)

def producer(consumer):

c = next(consumer)

for i in range(3):

consumer.send(i)

print 'produce value:%s ' % i

producer(consumer())

输出:

consume value:0

produce value:0

consume value:1

produce value:1

consume value:2

produce value:2

生产者和消费者交替执行。

小结

协程是在线程的基础上进行分时复用并发执行不同的程序段。它不是函数,也不是用户线程,更不是进程。

原文链接:https://blog.csdn.net/u010049696/article/details/112578887

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的线程协程都是用来实现并发的机制,但它们的实现方式有所不同。 Python线程的实现: Python线程是基于操作系统原生的线程实现的,即它们是由操作系统内核来调度和管理的。Python中的threading模块提供了线程的API,可以使用该模块来创建和管理线程线程的创建可以使用Thread类来实现,例如: ```python import threading def worker(): print('Worker') t = threading.Thread(target=worker) t.start() ``` 上述代码中,我们创建了一个名为worker()的函数,并将其作为线程的目标函数。我们使用Thread类创建了一个新的线程,并将worker函数作为其目标函数。最后,我们调用start()方法来启动线程Python协程的实现: Python协程是一种轻量级的并发机制,它可以在单个线程内实现多个任务的并发执行。Python协程的实现是基于生成器的,即协程是由生成器函数来实现的。Python中的asyncio模块提供了协程的API,可以使用该模块来创建和管理协程协程的创建可以使用async关键字和await关键字来实现,例如: ```python import asyncio async def worker(): print('Worker') asyncio.run(worker()) ``` 上述代码中,我们创建了一个名为worker()的协程函数,并使用async关键字来标识该函数是一个协程。我们使用asyncio模块的run()方法来运行该协程函数。协程函数中可以使用await关键字来等待其他协程或异步任务的完成。 总的来说,线程协程都是用来实现并发的机制,但线程是由操作系统内核来调度和管理的,而协程是由Python解释器来调度和管理的。线程适用于I/O密集型的任务,而协程适用于CPU密集型的任务。在Python中,协程的实现是基于生成器的,因此比线程更加轻量级和灵活。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值