首页 > 编程语言 > 详细

python协程和异步IO

时间:2019-05-08 00:48:21      阅读:160      评论:0      收藏:0      [点我收藏+]

1.并发、并行、同步、异步、阻塞、非阻塞

  并发:是指在同一个时间段内,有几个程序都处于启动运行到运行结束之间

  并行:在同一个时间点上,有几个程序同时运行

  同步:当一个同步操作发出去后,调用者一直等待返回消息结果,才能进行后续的操作 比如操作文件 打开文件 读取文件 都是同步操作

  异步: 当一个异步操作发出去后,调用者不能立刻得到消息结果 创建线程 都是异步操作

  阻塞:调用结果返回之前,当前线程会被挂起来,一直处于等待消息通知,不能执行其他业务

  非阻塞:调用结果返回之前,该函数不会阻塞当前线程 而立刻返回

2.IO多路复用select、poll、epoll

  select

    它通过一个select()系统调用来监视多个文件描述符,当select()返回后,该数组中就绪的文件描述符会被内核修改标志位,使进程能够获得这些文件描述符,从    而进行后续的修改

    缺点:单个进程能够监视的文件描述符的数量存在最大限制 一般1024

  poll

    本质跟select()没有区别 但是poll没有限制,使用的是链表存储

  epoll

    epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的    值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符    在系统调用时复制的开销。

    另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,    而poll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描        述符,当进程调用epoll_wait()时便得到通知。

  epoll实列

技术分享图片
 1 import selectors,socket
 2 def accept(sock, mask):
 3     conn, addr = sock.accept()
 4     print(accepted{}from{}.format(conn,addr))
 5     conn.setblocking(False)
 6     sel.register(conn,selectors.EVENT_READ, read)
 7 
 8 def read(conn, mask):
 9     data = conn.recv(1024)
10     if data:
11         print(echoing{}to{}.format(repr(data),conn))
12     else:
13         print(closing,conn)
14         sel.unregister(conn)
15         conn.close()
16 sel = selectors.DefaultSelector()
17 server = socket.socket()
18 server.bind((localhost, 9999))
19 server.listen(500)
20 server.setblocking(False)
21 sel.register(server, selectors.EVENT_READ, accept) #注册事件,只要来一个连接就调accept这个函数,
22 
23 while True:
24     events = sel.select()#这个select,看起来是select,有可能调用的是epoll,看你操作系统是Windows的还是Linux的
25                            #默认阻塞,有活动连接就返回活动连接列表
26     print(事件,events)
27 
28     for key,mask in events:
29         callback = key.data
30         callable(key.fileobj, mask)
View Code

  客户端

    

import socket,sys

server_address = (localhost, 9999)
 
# 创建100个 TCP/IP socket实例
socks = [ socket.socket(socket.AF_INET, socket.SOCK_STREAM) for i in range(100)]
 
# 连接服务端
print(connecting to %s port %s % server_address)
for s in socks:
    s.connect(server_address)
    s.send(bkehuduan)

    data = s.recv(1024)
    print(服务端回来的数据{}.format(data))
    if not data:
        print(连接失败)
        s.close()

 

python协程和异步IO

原文:https://www.cnblogs.com/gaosie/p/10829065.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!