其他
协程到底有什么用?6种I/O模式告诉你!
The following article is from 码农的荒岛求生 Author 陆小风
来源丨经授权转自 码农的荒岛求生(ID:escape-it)
作者丨陆小风
大家好,我是小风哥,今天来聊一聊协程的作用。
假设磁盘上有10个文件,你需要读取的内存,那么你该怎么用代码实现呢?
最简单的方法——串行
for file in files:
result = file.read()
process(result)
代码简单,容易理解
可维护性好,这代码交给谁都能维护的了(论程序员的核心竞争力在哪里)
稍好的方法,并行
def read_and_process(file):
result = file.read()
process(result)
def main():
files = [fileA,fileB,fileC......]
for file in files:
create_thread(read_and_process,
file).run()
# 等待这些线程执行完成
创建线程需要消耗系统资源,像内存等(想一想为什么?)
调度开销,尤其是当线程数量较多且都比较繁忙时(同样想一想为什么?)
创建多个线程不一定能加快I/O(如果此时设备处理能力已经饱和)
事件驱动 + 异步
相对于CPU的处理速度来说,IO是非常慢的
IO不怎么需要计算资源
event_loop = EventLoop()
def add_to_event_loop(event_loop, file):
file.asyn_read() # 文件异步读取
event_loop.add(file)
while event_loop:
file = event_loop.wait_one_IO_ready()
process(file.result)
def add_to_event_loop(event_loop, file):
file.asyn_read() # 文件异步读取
event_loop.add(file)
def main():
files = [fileA,fileB,fileC ...]
event_loop = EventLoop()
for file in files:
add_to_event_loop(event_loop, file)
while event_loop:
file = event_loop.wait_one_IO_ready()
process(file.result)
多线程 VS 单线程 + event loop
def add_to_event_loop(event_loop, file):
file.asyn_read() # 文件异步读取
event_loop.add(file)
def main():
files = [fileA,fileB,fileC......]
event_loop = EventLoop()
for file in files:
add_to_event_loop(event_loop, file)
while event_loop:
file = event_loop.wait_one_IO_ready()
process(file.result)
file = event_loop.wait_one_IO_ready()
for file in files: add_to_event_loop(event_loop, file)
一个好听的名字:Reactors模式
把回调也加进来
def IO_type_1(event_loop, io):
io.start()
def callback(result):
process_IO_type_1(result)
event_loop.add((io, callback))
while event_loop:
io, callback = event_loop.wait_one_IO_ready()
callback(io.result)
回调函数的问题
def start_IO_type_1(event_loop, io):
io.start()
def callback(result):
process_IO_type_1(result)
event_loop.add((io, callback))
发起IO
IO处理
问题出在哪里
Finally!终于到了协程
def start_IO_type_1(io):
io.start() # IO异步请求
yield # 暂停当前协程
process_IO_type_1(result) # 处理返回结果
def add_to_event_loop(io, event_loop):
coroutine = start_IO_type_1(io)
next(coroutine)
event_loop.add(coroutine)
while event_loop:
coroutine = event_loop.wait_one_IO_ready()
next(coroutine)
总结
单线程串行 + 阻塞式IO(同步)
多线程并行 + 阻塞式IO(并行)
单线程 + 非阻塞式IO(异步) + event loop
单线程 + 非阻塞式IO(异步) + event loop + 回调
Reactor模式(更好的单线程 + 非阻塞式IO+ event loop + 回调)
单线程 + 非阻塞式IO(异步) + event loop + 协程
2、MyBatis Plus + 两款神器,彻底解放双手,从此告别加班!爽!
3、Redis 为何使用近似 LRU 算法淘汰数据,而不是真实 LRU?
点分享
点点赞
点在看