浅谈python异步IO,同步IO,线程与进程~
主線程下的線程之間是可以通信的,但是父進程下的子進程之間不能主動通信,但是子進程想要實現通信也是可以的,可以選擇折中的方法來實現,比如multiprocessing.Queue,用法與線程中的queue基本一致,直接上例子:
import threading from multiprocessing import Process,Queue import time def thre(qq):qq.put([1,'xixi',2])if __name__ =='__main__':q = Queue()p = Process(target=thre,args=(q,))#進程中,因為進程內存是獨立的,所以不能相互調用,必須傳入參數,這個q其實是復制了一份Queue的實例,如果和線程一樣不傳參數,就會報錯** not find。。。因為內存不共享。 #p =threading.Thread(target=thre) #線程中,不傳參數是可以調用函數thre,因為他們是在同一個內存地址下操作【上面改為def thre():】,當然傳參數也沒問題。 p.start()print(q.get())#進程之間想要有聯系,主動無法聯系,這是硬傷,就如qq和word一樣,但是如果非要他們有聯系,就是從word復制文字到qq里(或者qq復制圖片文字到word里面這樣),這樣貌似兩者有聯系,實際上只是克隆了那段文字的關系,但是看起來好像就有聯系了,那么python中process之間的通信就是可以考慮通過 Queue來實現,Queue內部操作其實就是通過pickle的功能來實現傳參數等各種聯系的 還有一個是pipe:通過管道來傳遞,也是建立一個pipe的實例化對象。 from multiprocessing import Process,Pipedef f(conn):conn.send('balabala')print(conn.recv())if __name__=='__main__':parent_conn,child_conn=Pipe()#實例化后是返回兩個值,一個是父接頭一個是子接頭,因為是管道。p = Process(target=f,args=(child_conn,))p.start()print(parent_conn.recv())parent_conn.send('babababa')這樣也能實現數據的傳遞,但都不是共享
進程之間要實現共享,需要用manager。
from multiprocessing import Process,Manager import time,osdef thre(dd,ll):dd[os.getpid()] = os.getppid()ll.append(os.getpid())print(ll)print(dd)if __name__ =='__main__':manager = Manager()d = manager.dict()l = manager.list(range(3))t_list = []for i in range(10):p = Process(target=thre,args=(d,l))p.start()t_list.append(p)for res in t_list:res.join()#等待的意思此時字典 d 和 列表 l,他們的數據同時都可以被進程修改覆蓋,只不過我這里用的是os.getpid()獲取的數據不一致,如果是一致的,那么最終字典只有一個k-v,列表是10個一樣的數據。
?
進程鎖的存在是為了輸出同一個屏幕不要亂。。。僅此而已
?
進程池的作用和線程中的信號量差不多,同一時間允許幾個進程同時運行
其中有 apply 和apply_async,一個是串行操作,一個是并行操作。
協程:可以實現高并發,本質上就是單線程,一個cpu支持上萬個協程并發
gevent(自動觸發) 和 greenlet(手動觸發)
運行結果:
runing 1 ...
running 3 ...
running 5 ...
end?
running 2 ...
running 4
----------------------
sleep相當于觸發的按鈕,出現一次sleep,就去找下一個函數中的內容打印等操作,sleep內的時間相當于他卡幾次,sleep(3)相當于卡3秒,如果其他已經沒卡著,就馬上執行沒卡著的語句,知道最后回來等到時間結束執行最后這個語句。協程用于多并發爬蟲中效果很好。
運行結果:
GET https://www.python.org/
recv bytes 48860 from https://www.python.org/
GET http://km.58.com/
recv bytes 104670 from http://km.58.com/
GET http://kan.sogou.com/dongman/
recv bytes 12713 from http://kan.sogou.com/dongman/
GET http://news.sohu.com/
recv bytes 170935 from http://news.sohu.com/
同步時間: 3.780085563659668
GET https://www.python.org/
GET http://km.58.com/
GET http://kan.sogou.com/dongman/
GET http://news.sohu.com/
recv bytes 12690 from http://kan.sogou.com/dongman/
recv bytes 170935 from http://news.sohu.com/
recv bytes 104670 from http://km.58.com/
recv bytes 48860 from https://www.python.org/
異步時間: 2.5934762954711914
?
用戶空間和內核空間(kernel)
現在操作系統中都是采用虛擬存儲器,操作系統的核心是內核,獨立于普通的應用程序,可以訪問受保護的內存空間,也有訪問硬件設備的權限,為了保證用戶進程不能直接操作內核(kernel),保證內核的安全,操作系統把虛擬空間分為兩部分,一部分為內核空間,一部分為用戶空間。
進程切換
為了控制進程的執行,內核必須有能力掛起在CPU上運行的進程,并且恢復以前掛起的某個進程的執行,這種行為稱作進程切換,因此,任何進程都是在操作系統內核的支持下運行的,與內核緊密相連。
從一個進程的運行轉到另一個進程上運行,其實就是保存上下文就切換了。下次再來又從之前保存的位置開始。
進程的阻塞:
正式執行的進程,由于期待的某件事情并未發生,如請求系統資源失敗等待,等待某種操作的完成,新數據尚未達到或無新工作開始等,則有系統自動執行阻塞原語,使自己由原來的運行狀態轉為阻塞狀態暫停等待()
。可見,進程的阻塞是進程自身的一種主動行為,也因此只有處于運行狀態的進程(獲得CPU),才可能將其轉為阻塞狀態,當進程進入阻塞狀態時候,不耗費CPU資源的。
緩存I/O
又被成為標準IO,大多數文件系統默認I/O操作都是緩存I/O,在Linux的緩存I/O機制當中,操作系統會將I/O的數據緩存在文件系統的頁緩存中,也就是說,文件數據會被拷貝到系統內核的緩沖區中,然后再從系統內核的緩沖區拷貝到用戶的進程內存里也就是應用程序的地址空間。缺點就是數據會在用戶進程應用程序地址空間和內核空間反復拷貝操作,這時對于CPU和內存的開銷很大。
I/O模式
同步IO和異步IO:
同步IO中有:阻塞IO(blocking I/O),非阻塞IO(non-blocking I/O),多路復用IO(I/O multiplexing) 信號驅動(實際中不常用。在此暫時不記錄筆記)
異步I/O(asynchronous I/O)
阻塞IO:發起請求,然后等待數據準備(此時進程阻塞等待),直到數據準備好接受時,又到內核空間開始copy給用戶進程,此時又一次阻塞等待,直到數據全部發給用戶進程(客戶端)。
非阻塞IO:發起請求后,瘋狂發送驗證,數據未準備好時,并不會阻塞block,而是返回一個error給用戶進程,用戶進程會驗證是否error,是就繼續發出請求,來回驗證,(此時由于進程沒有阻塞,還可以干其他事,)不是就到了內核空間開始copy數據,此時其實還是阻塞,如果數據小會很快,數據大還是會感受到卡。最后用戶收到完整數據。
多路復用I/O:一次發起幾百次請求鏈接,無論哪條鏈接有數據回復,都會通知用戶進程開始接受數據,此時那幾條鏈接又開始進行內核copy直到進程收到完整數據(其實這里也是阻塞的)。這個模式的核心其實是用非阻塞IO的方式來驅動,所以形成多路復用,在用戶看來已經是多并發了。
異步I/O:這個就牛逼了,他發起請求,當場就收到回復‘去干你其他的事’,此時該進程開始其他部分運行,并未有任何阻塞,收到數據時,直接后臺開始內核copy,全部搞完以后直接‘送快遞到家門口’,給一個信號通知,用戶進程順手就接受了數據,此時整個進程根本沒有任何阻塞過程!這就是異步IO。
selectors
selectors中涵蓋了select,poll,epoll,詳細實例:
這個可以進行多并發運行。
好了 異步同步線程進程就到這了,人生苦短,我用python。
轉載于:https://www.cnblogs.com/Jason504327775/p/8503516.html
總結
以上是生活随笔為你收集整理的浅谈python异步IO,同步IO,线程与进程~的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CODEVS-2050 派对灯
- 下一篇: Apache Solr Velocity