gevent 入门篇
并发编程模型主要有:多进程,多线程,事件驱动,协程。gevent 是基于协程的异步框架,它需要依赖于 greenlet.gevent 有什么样的优势? 先来通过一个简单的例子对比同步执行一个方法和使用 gevent 的异步方式。
普通的单线程同步执行任务
import time
def sync_task():
#do something
time.sleep(1)
def sync_run():
start = time.time()
for i in range(10):
sync_task()
end = time.time()
print("sync task executed in %f second"%(end-start))
打印结果:async task executed in 10.012671 second
如果换成多线程会是什么情况呢?
import threading
def multi_thread_run():
start = time.time()
for i in range(10):
t = threading.Thread(target=sync_task)
t.start()
end = time.time()
print("multi thread task executed in %f second"%(end-start))
打印结果是:multi thread task executed in 0.002425 second,这个时间简直亮瞎了,其实这段程序有问题,子线程还没执行完时,主线程就结束了,因此时间才那么短,其实要稍稍修改:
def multi_thread_run():
start = time.time()
threads = []
for i in range(300):
t = threading.Thread(target=sync_task)
threads.append(t)
t.start()
for t in threads:
t.join()
end = time.time()
print("multi thread task executed in %f second"%(end-start))
等所有子线程执行完之后再执行主线程,看看打印结果:
multi thread task executed in 1.002796 second
这是一个比较正常的结果。
换成 gevent 后会怎样呢?
import gevent
def async_task():
#do something
gevent.sleep(1)
def async_run():
start = time.time()
coroutins = []
for i in range(10):
coroutins.append(gevent.spawn(async_task))
gevent.joinall(coroutins)
end = time.time()
print("async task executed in %f second"%(end-start))
打印输出:async task executed in 1.002012 second,gevent.spawn() 方法会创建一个协程实例,gevent.joinall() 是使所有的线程执行完了之后在运行主线程,这跟多线程编程是同样的概念。发现 gevent 比多线程也没快多少,那 gevent 究竟有什么优势。现在假设把上面的 10 替换成 1000,也就是 1000 线程与 1000 个 coroutine 之间的比较,会出现什么结果呢?如果是用线程的话直接报错了:thread.error: can't start new thread
,而用协程就不会出现这种问题。
coroutine 相比 thread 的优势在于:
- 创建 threade 的成本高,而创建 coroutine 的成本很低
- thread 的上下文切换成本高,而 coroutin 的切换速度很快
- thread 的上下文切换取决于 cpu,而 coroutine 由自己控制
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论