基于套接字的IO模型

# 讲一下IO
# 同步调用:串行,从上到下,等待结果完了在执行下一个。
# 异步调用:并发,直接扔进去,不用等待,并发执行  异步一般跟回调机制一起用
#
# 同步 不等于 IO堵塞
#
# 堵塞:就是遇到IO了,一般线程遇到IO,cup资源就走了, 协程是为了解决cup继续执行本线程
# 举个例子:家教老师,来上课,我还没准备好,老师说我先去别人家上课一会再回来,有了协程以后,相当于,我哥说:先给我补课吧,一会再给我弟弟补课
#
# 非堵塞:相反
#
#
# 套接字下:阻塞IO和非阻塞IO
# 阻塞IO:就是之前写的代码,他会一直等待,accept,recv和send都是IO
# accept和recv:等待对方的数据,把数据从操作系统缓冲区拷贝到程序缓冲区
# send:直接把数据从程序缓冲区,发送到操作系统缓冲区
#
# 非阻塞IO:
# import socket
# master = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#
# #加上这句代码:
# master.setblocking(False)  # 不许堵塞
#     while 等待数据
#         问:有数据了吗?
#         答:给你个信号。现在没数据,你可以干别的事
#     有数据以后,就连接成功。
# 非堵塞IO的缺点:
#     干别的事情的时候,消息来了,不能及时响应
#     while死循环,没有堵塞,一直询问都是没用的,会导致CUP做无用功。
# 所以说不建议使用
# import socket
# master = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# master.bind(("127.0.0.1",8080))
# master.listen(5)
# master.setblocking(False)  #非堵塞IO
# con_list = []
# w_list = []
# while True:
#     try:
#         con,a=master.accept()
#         con_list.append(con)
#         pass
#     except BlockingIOError:
#         # print("干别的事情")
#         del_list = []
#
#         for con in con_list:
#             try:
#                 data = con.recv(1024)
#                 if not data:
#                     del_list.append(con)
#                     continue
#                 #send 也是IO,怎么办,放到一个列表里,待会去处理
#                 # con.send(data.decode("utf-8").upper().encode("utf-8"))
#                 w_list.append((con,data.decode("utf-8").upper().encode("utf-8")))
#             except BlockingIOError:
#                 continue
#             except Exception:
#                 pass
#                 con.close()
#                 del_list.append(con)
#         del_wlist = []
#         for item in w_list:
#             try:
#                 item[0].send(item[1])
#                 del_wlist.append(item)
#             except BlockingIOError:
#                 pass
#         for item in del_wlist:
#             w_list.remove(item)
#         for con in del_list:
#             con_list.remove(con)
# master.close()

# 客户端
# import socket
#
# client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#
# client.connect(("127.0.0.1",8080))
#
# while True:
#     data = input("<<<<")
#     client.send(data.encode("utf-8"))
#     data = client.recv(1024)
#     print(data.decode("utf-8"))
# client.close()




# 多路复用IO模型:包括等待数据,拷贝数据 和 中介
#     链接多了以后,效率就高了
#     一个链接的时候肯定比堵塞IO效率低
# 玩法:select
# 优点:可以监控多个套接字,效率比堵塞要高,比非堵塞也高
# 缺点:随着监控的越多,那就效率越低,因为他是列表遍历
#         poll只是比select监控的要多
# 要解决,还得靠epoll
# epoll 只支持linux 不支持windows,我也是醉了
# import select
# import socket
#
# master = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# master.bind(("127.0.0.1",8080))
# master.listen(5)
# master.setblocking(False)
#
# rlist = [master,]
# wlist = []
# wdata = {}
# while True:
#     rl,wl,xl =select.select(rlist,wlist,[],0.5)
#     # print("rl:",rl)
#     # print("wl:",wl)
#     # print("xl:",xl)
#
#     for i in rl:
#         if i == master:
#             con,a = i.accept()
#             rlist.append(con)
#         else:
#             try:
#                 data = i.recv(1024)
#                 if not data:
#                     i.close()
#                     rlist.remove(i)
#                     continue
#                 wlist.append(i)
#                 wdata[i] = data.decode("utf-8").upper().encode("utf-8")
#             except Exception:
#                 i.close()
#                 rlist.remove(i)
#     del_wlist = []
#     for i in wl:
#         i.send(wdata[i])
#         del_wlist.append(i)
#
#     for i in del_wlist:
#         wlist.remove(i)
#         wdata.pop(i)



# 异步IO模型,这个暂时等爬虫的时候再深究
# 用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。
#
#
#
View Code

基于套接字的IO模型:
1.堵塞IO
2.非堵塞IO
3.多路复用IO
4.异步IO模型

posted @ 2020-08-04 15:48    阅读(128)  评论(0编辑  收藏  举报