协程和IO模型

为什么会有协程的存在?

线程的创建也会占用一定的时间,所以直接用协程模块儿来手动切换,就会剩下来创建线程的时间

 

 

 

 

 

 

利用协程写爬虫:

from gevent import monkey
monkey.patch_all()
import requests
import gevent
def get_url(url):
    return len(requests.get(url).content.decode())


g1 = gevent.spawn(get_url, "https://www.baidu.com")
g2 = gevent.spawn(get_url, "https://www.hao123.com")
g3 = gevent.spawn(get_url, "https://www.sogo.com")
g4 = gevent.spawn(get_url, "https://www.taobao.com")
gevent.joinall([g1, g2, g3, g4])
print(g1.value)
print(g2.value)
print(g3.value)
print(g4.value)

  

 

 

 

 

 

 

IO模型:

 

平常正常写socket的就是阻塞IO模型

 

 

非阻塞IO模型:

server端:
import socket
sk = socket.socket()
sk.bind(("127.0.0.1", 9000))
sk.setblocking(False)
sk.listen()
con_l = []
del_con_l = []
while 1:
    try:
        conn, addr = sk.accept()
        print("和{}建立连接成功".format(addr))
        con_l.append(conn)
    except:
        for con in con_l:
            try:
                info = con.recv(1024).decode()
                if info == "":
                    del_con_l.append(con)
                    continue
                print(info)
                con.send(b"byebye")
            except:
                pass
        for con in del_con_l:
            con.close()
            con_l.remove(con)
        del_con_l.clear()



client端:
import time
from threading import Thread
import socket

def func():
    sk = socket.socket()
    sk.connect(("127.0.0.1", 9000))
    time.sleep(10)
    sk.send(b"hello")
    info = sk.recv(1024).decode()
    print(info)
    sk.close()

if __name__ == '__main__':
    for i in range(20):
        Thread(target=func).start()

  

 

多路复用IO模型:

 

server端:
import socket
import select
sk = socket.socket()

sk.bind(("127.0.0.1", 8090))
sk.setblocking(False)
sk.listen()
read_lst = [sk]
while 1:
    r_lst, w_lst, x_lst = select.select(read_lst, [], [])
    for i in r_lst:
        if i is sk:
            conn, addr = i.accept()
            read_lst.append(conn)
        else:
            info = i.recv(1024).decode()
            if info == "":
                i.close()
                read_lst.remove(i)
                continue
            print(info)
            i.send(b"goodbye")



client:
import time
from threading import Thread
import socket

def func():
    sk = socket.socket()
    sk.connect(("127.0.0.1", 8090))
    time.sleep(5)
    sk.send(b"hello")
    info = sk.recv(1024).decode()
    print(info)
    sk.close()

if __name__ == '__main__':
    for i in range(20):
        Thread(target=func).start()

  

 

 

各种IO模型的比较:

posted @ 2019-04-07 09:43  Qimisun  阅读(280)  评论(0编辑  收藏  举报