并发编程5

时间:2020-04-28
本文章向大家介绍并发编程5,主要包括并发编程5使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

IO模型

五种IO模型
   * blocking IO           阻塞IO
    * nonblocking IO      非阻塞IO
    * IO multiplexing      IO多路复用
   * signal driven IO     信号驱动IO
    * asynchronous IO    异步IO
    由signal driven IO(信号驱动IO)在实际中并不常用,所以主要介绍其余四种IO Model。
   同步异步
阻塞非阻塞
常见的网络阻塞状态:
accept
    recv
    recvfrom
   
    send虽然它也有io行为 但是不在我们的考虑范围
阻塞IO
"""
我们之前写的都是阻塞IO模型 协程除外
"""
import socket


server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)


while True:
    conn, addr = server.accept()
    while True:
        try:
            data = conn.recv(1024)
            if len(data) == 0:break
            print(data)
            conn.send(data.upper())
        except ConnectionResetError as e:
            break
    conn.close()
   
'''
在服务端开设多进程或者多线程 进程池线程池 其实还是没有解决IO问题
该等的地方还是得等 没有规避
只不过多个人等待的彼此互不干扰
'''
非阻塞型IO

如何自己实现非阻塞型IO

import socket
import time


server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)
server.setblocking(False)
# 将所有的网络阻塞变为非阻塞
r_list = []
del_list = []
while True:
    try:
        conn, addr = server.accept()
        r_list.append(conn)
    except BlockingIOError:
        # time.sleep(0.1)
        # print('列表的长度:',len(r_list))
        # print('做其他事')
        for conn in r_list:
            try:
                data = conn.recv(1024# 没有消息 报错
               if len(data) == 0# 客户端断开链接
                   conn.close()  # 关闭conn
                    # 将无用的conn从r_list删除
                   del_list.append(conn)
                    continue
                conn.send(data.upper())
            except BlockingIOError:
                continue
            except ConnectionResetError:
                conn.close()
                del_list.append(conn)
        # 挥手无用的链接
       for conn in del_list:
            r_list.remove(conn)
        del_list.clear()

# 客户端
import socket


client = socket.socket()
client.connect(('127.0.0.1',8081))


while True:
    client.send(b'hello world')
    data = client.recv(1024)
    print(data)

PS:虽然非阻塞IO给人的感觉非常顺滑~,但是非阻塞型IO会长时间占用CPU,使得CPU不停的空转,因此在实际应用中也不会使用到非阻塞型IO

IO多路复用
'''
IO多路复用,听名字就知道肯定是多个对象。
在监管一个对象时IO多路复用甚至连阻塞IO都不如
但时IO多路复用可以监管多个对象
监管机制是操作系统本身就有的 如果你想要用该监管机制(select)
需要你导入对应的select模块
'''
import socket
import select


server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
server.setblocking(False)
read_list = [server]


while True:
    r_list, w_list, x_list = select.select(read_list, [], [])
    """
   帮你监管
  一旦有人来了 立刻给你返回对应的监管对象
  """
    # print(res) # ([<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>], [], [])
    # print(server)
    # print(r_list)
    for i in r_list#
        """针对不同的对象做不同的处理"""
        if i is server:
            conn, addr = i.accept()
            # 也应该添加到监管的队列中
           read_list.append(conn)
        else:
            res = i.recv(1024)
            if len(res) == 0:
                i.close()
                # 将无效的监管对象 移除
               read_list.remove(i)
                continue
            print(res)
            i.send(b'heiheiheiheihei')

# 客户端
import socket


client = socket.socket()
client.connect(('127.0.0.1',8080))


while True:

    client.send(b'hello world')
    data = client.recv(1024)
    print(data)

PS:在不同的平台有不同的监管机制,相对的监管数量也有差异

但是selectors模块可以根据你程序运行的不同平台帮你选择对应的监管机制

异步IO
'''
异步IO是所有所有模型中效率最高,并且是应用最广泛的一种
模块与框架——asyncio模块
——sanic tronado twisted异步框架
'''
asyncio模块
import threading
import asyncio


@asyncio.coroutine
def hello():
    print('hello world %s'%threading.current_thread())
    yield from asyncio.sleep(1# 换成真正的IO操作
   print('hello world %s' % threading.current_thread())


loop = asyncio.get_event_loop()
tasks = [hello(),hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

原文地址:https://www.cnblogs.com/bailongcaptain/p/12794807.html