1、協程python
2、異步IO_Gevent數據庫
3、協程異步IO操做編程
4、事件驅動模型windows
5、IO多路複用多線程
6、異步IO理論app
1、回顧
線程 vs 進程
線程:CPU最小調度單位,內存共享;
線程同時修改同一份數據是必須加鎖,mutex互斥鎖
遞歸鎖
join 等待線程執行結果;
進程:資源集合
2、多進程
IO操做不佔用CPU
計算佔用CPU
python多線程不適合CPU密集操做型的任務,適合IO密集型的任務;
啓動一個多進程:
import multiprocessing
import time異步
def run(name):
time.sleep(2)
print("hello")
if __name__ == '__main__':
for i in range(10):
p = multiprocessing.Process(target=run, args=('bob',))
p.start()
取進程ID
os.getppid() #父進程
os.getpid() #子進程
每一個進程都是由父進程啓動;socket
3、進程Queue數據傳遞
form multiprocessing import Process, Queue
子線程的queue能訪問父線程的queue,內存共享;
子進程的queue不能訪問父進程的queue,內存獨立;
子進程要訪問父進程的queue,必須傳入進程queue;
至關於克隆一份queue給子進程;pickle過程;
4、pipe進程間管道通訊
from multiprocession import Process, Pipe
parent_conn,child_conn = Pipe()
管道兩頭,一頭傳給子進程,一頭留在父進程;
process(target=f,args=(child_conn))
parent_conn.recv() #父進程裏收數據
def f():
child_conn.send() #子進程裏發數據async
進程數據共享:
with Manager() as manager:
d=manager.dict() #生成一個字典,可在多個進程間共享和傳遞;
l=manager.list() #生成一個列表,可在多個進程間共享和傳遞;函數
5、進程鎖
from multiprocession import Lock
lock = Lock()
lock.acquire()
lock.release()
進程鎖存在的意義,屏幕打印;
6、進程池
from multiprocession import Pool
pool = Pool(5) #容許進程池裏同時放入5個進程;
pool.apply(func=Foo,args=(i,),callback=Bar)
pool.close()
pool.join()
先close 再join
apply 是同步執行,串行;
apply_async 是異步執行,並行
在windows上起多進程必須加 if __name__ == '__main__':
若是手動執行腳本會執行,若是調用不執行;
callback 回調函數;前面函數執行完後執行回調函數;
回調函數是主進程調用,主進程鏈接數據庫長鏈接;
7、協程
協程就是一種用戶態的輕量級線程;
遇到IO操做就切換;
greenlet #手動切換協程
form greenlet import greenlet
def test1():
print(12)
gr2.swithc()
print(34)
gr2.swithc()
def test2():
print(56)
gr1.swithc()
print(78)
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.swithc()
gevent #自動切換協程
import gevent
def foo():
print("running foo")
gevent.sleep(2)
print("swithc to foo")
def bar():
print("running bar")
gevent.sleep(2)
print("swithc to bar")
gevent.joinall([gevent.spawn(foo),gevent.spawn(bar),])
from gevent import monkey
monkey.patch_all() #把當前程序的全部的io操做單獨的作上標記
打上補丁gevent能識別IO操做;
8、事件驅動模型 檢測到事件,放入事件隊列,調用各自的函數處理事件; 事件驅動是一種編程範式;9、IO多路複用 1.等待數據準備 2.將數據從內核空間拷貝到進程中; 阻塞I/O,等待數據和拷貝數據都阻塞 非阻塞,等待數據時非阻塞,特色是用戶須要不斷得詢問內核數據有沒有準備好; I/O多路複用,select,poll,epoll 異步I/O, epoll沒有最大鏈接數的限制; asyncio 異步IO10、IO多路複用select代碼實現 import select import socket import queue server = socket.socket() server.bind('localhost',9000) server.listen(1000) server.setblocking(False) #不阻塞 inputs = [server,] outputs = [] readable,writeable,exceptional = select.select(inputs,outputs,inputs) server.accept()