为什么会有协程的存在?
线程的创建也会占用一定的时间,所以直接用协程模块儿来手动切换,就会剩下来创建线程的时间
利用协程写爬虫:
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模型的比较: