久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

多線程和多進程不可能是雞肋,!只因你還不會!最全的進階資料,!

 ly88 2018-01-29

不管你是大牛還是萌新,,學好Python這些資料是必須用得到的!你不會這些比較基礎的知識你拿什么東西來做項目呢,?特別是c語言對底層知識掌握更加的嚴格,!今天給大家打來比較基礎的干貨合集,,衷心的希望能幫助到大家學好Python!

multiprocessing模塊

由于GIL的存在,,python中的多線程其實并不是真正的多線程,,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程,。

multiprocessing包是Python中的多進程管理包,。與threading.Thread類似,它可以利用multiprocessing.Process對象來創(chuàng)建一個進程,。該進程可以運行在Python程序內部編寫的函數(shù),。該Process對象與Thread對象的用法相同,也有start(), run(), join()的方法,。

此外multiprocessing包中也有Lock/Event/Semaphore/Condition類 (這些對象可以像多線程那樣,,通過參數(shù)傳遞給各個進程),用以同步進程,,其用法與threading包中的同名類一致,。所以,multiprocessing的很大一部份與threading使用同一套API,,只不過換到了多進程的情境,。

multiprocessing模塊的功能眾多:支持子進程、通信和共享數(shù)據(jù),、執(zhí)行不同形式的同步,提供了Process,、Queue,、Pipe、Lock等組件,,進程沒有任何共享狀態(tài),,進程修改的數(shù)據(jù),改動僅限于該進程內,。

Process類的介紹

Process(target = talk,args = (conn,addr))#由該類實例化得到的對象,,表示一個子進程中的任務(尚未啟動)

group參數(shù)未使用,值始終為None,,

target表示調用對象,,即子進程要執(zhí)行的任務,

args表示調用對象的位置參數(shù)元組,,args=(1,2,'egon',),,

kwargs表示調用對象的字典,kwargs={'name':'egon','age':18},

name為子進程的名稱,。

方法:p.start():啟動進程,,并調用該子進程中的p.run()

p.run():進程啟動時運行的方法,,正是它去調用target指定的函數(shù),我們自定義類的類中一定要實現(xiàn)該方法

p.terminate():強制終止進程p,,不會進行任何清理操作,,如果p創(chuàng)建了子進程,該子進程就成了僵尸進程,,使用該方法需要特別小心這種情況,。如果p還保存了一個鎖那么也將不會被釋放,進而導致死鎖

p.is_alive():如果p仍然運行,,返回True

p.join([timeout]):主線程等待p終止(強調:是主線程處于等的狀態(tài),,而p是處于運行的狀態(tài))。timeout是可選的超時時間,,需要強調的是,,p.join只能join住start開啟的進程,而不能join住run開啟的進程

屬性:p.daemon:默認值為False,,如果設為True,,代表p為后臺運行的守護進程,當p的父進程終止時,,p也隨之終止,,并且設定為True后,p不能創(chuàng)建自己的新進程,,必須在p.start()之前設置

p.name:進程的名稱

p.pid:進程的pid,,每個進程都會開啟一個python解釋器去完成,對應一個pid號,。

p.exitcode:進程在運行時為None,、如果為–N,表示被信號N結束,。

p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串,。這個鍵的用途是為涉及網絡連接的底層進程間通信提供安全性,這類連接只有在具有相同的身份驗證鍵時才能成功,。

使用方式分為直接調用和繼承類方式調用:

協(xié)程函數(shù)

協(xié)程擁有自己的寄存器上下文和棧,。協(xié)程調度切換時,將寄存器上下文和棧保存到其他地方,,在切回來的時候,,恢復先前保存的寄存器上下文和棧。因此:

協(xié)程能保留上一次調用時的狀態(tài)(即所有局部狀態(tài)的一個特定組合),,每次過程重入時,,就相當于進入上一次調用的狀態(tài),換種說法:進入上一次離開時所處邏輯流的位置。

gevent模塊實現(xiàn)協(xié)程

Python通過yield提供了對協(xié)程的基本支持,,但是不完全,。而第三方的gevent為Python提供了比較完善的協(xié)程支持。

gevent是第三方庫,,通過greenlet實現(xiàn)協(xié)程,,其基本思想是:

當一個greenlet遇到IO操作時,比如訪問網絡,,就自動切換到其他的greenlet,,等到IO操作完成,再在適當?shù)臅r候切換回來繼續(xù)執(zhí)行,。由于IO操作非常耗時,,經常使程序處于等待狀態(tài),有了gevent為我們自動切換協(xié)程,,就保證總有greenlet在運行,,而不是等待IO。

由于切換是在IO操作時自動完成,,所以gevent需要修改Python自帶的一些標準庫,,這一過程在啟動時通過monkey patch完成:

實際代碼里,我們不會用gevent.sleep()去切換協(xié)程,,而是在執(zhí)行到IO操作時,,gevent自動切換,代碼如下:

I/O模型

一共有五種類型的I/O模型:1.阻塞I/O:全程阻塞,,2.非阻塞I/O:發(fā)送多次系統(tǒng)調用,,3.IO多路復用(監(jiān)聽多個連接)4.異步IO5.驅動信號

對于一個network IO (這里我們以read舉例),它會涉及到兩個系統(tǒng)對象,,一個是調用這個IO的process (or thread),,另一個就是系統(tǒng)內核(kernel)。當一個read操作發(fā)生時,,它會經歷兩個階段:

  •  等待數(shù)據(jù)準備 (Waiting for the data to be ready)

  •  將數(shù)據(jù)從內核拷貝到進程中 (Copying the data from the kernel to the process)

1.阻塞I/O

在linux中,默認情況下所有的socket都是blocking,,一個典型的讀操作流程大概是這樣:

這兩個階段都是阻塞的,,在進行的時候不可以做其他的任務,所以是全程阻塞,。

non-blocking IO(非阻塞IO)

copy data的時候是阻塞的,,等待數(shù)據(jù)時在監(jiān)聽,數(shù)據(jù)不來就做其他的事,,數(shù)據(jù)來了就復制數(shù)據(jù),。

優(yōu)點:能夠在等待任務完成的時間里干其他活了(包括提交其他任務,也就是 “后臺” 可以有多個任務在同時執(zhí)行)。

缺點:任務完成的響應延遲增大了,,因為每過一段時間才去輪詢一次read操作,,而任務可能在兩次輪詢之間的任意時間完成。這會導致整體數(shù)據(jù)吞吐量的降低,。并且數(shù)據(jù)也不是實時的,,在數(shù)據(jù)沒來時進行某個操作,操作期間數(shù)據(jù)來了,,但是他不能立刻去copy data,。

IO multiplexing(IO多路復用)

IO multiplexing就是select,epoll實現(xiàn)的,。有些地方也稱這種IO方式為event driven IO,。select/epoll的好處就在于單個process就可以同時處理多個網絡連接的IO。它的基本原理就是select/epoll這個function會不斷的輪詢所負責的所有socket,,當某個socket有數(shù)據(jù)到達了,,就通知用戶進程。它的流程如圖:

當用戶進程調用了select,,那么整個進程會被block,,而同時,kernel會“監(jiān)視”所有select負責的socket,,當任何一個socket中的數(shù)據(jù)準備好了,,select就會返回。這個時候用戶進程再調用read操作,,將數(shù)據(jù)從kernel拷貝到用戶進程,。

select僅僅使用I/O多路復用就完成了并發(fā)。一開始只監(jiān)聽sock,,一有客戶端來連接將conn加入監(jiān)聽,,然后傳數(shù)據(jù)過來就只監(jiān)聽conn傳數(shù)據(jù),簡單來說select只監(jiān)聽有變化的套接字,,沒有變化的套接字傳輸還是按照之前學的套接字之間的數(shù)據(jù)傳輸,。

結論: select的優(yōu)勢在于可以處理多個連接,不適用于單個連接,。

Asynchronous I/O(異步IO)

全程無阻塞,,異步就是用戶進程發(fā)起read操作之后,立刻就可以開始去做其它的事,。而另一方面,,從kernel的角度,當它受到一個asynchronous read之后,,首先它會立刻返回,,所以不會對用戶進程產生任何block。然后,kernel會等待數(shù)據(jù)準備完成,,然后將數(shù)據(jù)拷貝到用戶內存,,當這一切都完成之后,kernel會給用戶進程發(fā)送一個signal,,告訴它read操作完成了,。

到目前為止,已經將四個IO Model都介紹完了?,F(xiàn)在回過頭來回答最初的那幾個問題:blocking和non-blocking的區(qū)別在哪,,synchronous IO和asynchronous IO的區(qū)別在哪。

調用blocking IO會一直block住對應的進程直到操作完成,,而non-blocking IO在kernel還準備數(shù)據(jù)的情況下會立刻返回,。

各個IO Model的比較如圖所示:

non-blocking IO中,雖然進程大部分時間都不會被block,,但是它仍然要求進程去主動的check,,并且當數(shù)據(jù)準備完成以后,也需要進程主動的再次調用recvfrom來將數(shù)據(jù)拷貝到用戶內存,。而asynchronous IO則完全不同,。它就像是用戶進程將整個IO操作交給了他人(kernel)完成,然后他人做完后發(fā)信號通知,。在此期間,,用戶進程不需要去檢查IO操作的狀態(tài),也不需要主動的去拷貝數(shù)據(jù),。

selectors模塊(基于select機制實現(xiàn)的IO多路復用)

這個模塊已經封裝了select,,poll,和epoll實現(xiàn)I/O多路復用,。

windows下只有select,,linux上還有poll和epoll。

select缺點每次調用都要將所有文件描述符copy到內核空間導致效率低,,每次都要遍歷所有的fd,,是否有數(shù)據(jù)訪問。最大連接數(shù)1024,,poll只是沒有連接數(shù)限制,。

epoll:第一個函數(shù)創(chuàng)建epoll句柄,只有第一次要將所有文件描述符copy到內核空間,,第二個函數(shù)回調函數(shù),某一個函數(shù)某一個動作成功完成后會觸發(fā)的函數(shù),,為所有fd綁定回調函數(shù),,一旦有數(shù)據(jù)訪問觸發(fā)此回調函數(shù),回調函數(shù)將fd放到鏈表中。第三個函數(shù)判斷鏈表是否為空,。

q=Queue.Queue類即是一個隊列的同步實現(xiàn),。隊列長度可為無限或者有限??赏ㄟ^Queue的構造函數(shù)的可選參數(shù) maxsize來設定隊列長度,。如果maxsize小于1就表示隊列長度無限。

q.put(10) 調用隊列對象的put()方法在隊尾插入一個項目,。put()有兩個參數(shù),,第一個item為必需的,為插入項目值,; 第二個block為可選參數(shù),,默認為 1。如果隊列當前為空且block為1,,put()方法就使調用線程暫停,直到空出一個數(shù)據(jù)單元,。如果block為0, put方法將引發(fā)Full異常,。

將一個值從隊列中取出 q.get() 調用隊列對象的get()方法從隊頭刪除并返回一個項目,。可選參數(shù)為block,,默認為True,。如果隊列為空且 block為True,get()就使調用線程暫停,,直至有項目可用,。如果隊列為空且block為False,隊列將引發(fā)Empty異常,。

join() 阻塞進程,,直到所有任務完成,需要配合另一個方法task_done,。

task_done() 表示某個任務完成,。每一條get語句后需要一條task_done。

其他常用方法

此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回隊列的大小

q.empty() 如果隊列為空,,返回True,反之False

q.full() 如果隊列滿了,,返回True,反之False

q.full 與 maxsize 大小對應

q.get([block[, timeout]]) 獲取隊列,timeout等待時間

q.get_nowait() 相當q.get(False)非阻塞
q.put(item) 寫入隊列,,timeout等待時間

q.put_nowait(item) 相當

q.put(item, False)

q.task_done() 在完成一項工作之后,,

q.task_done() 函數(shù)向任務已經完成的隊列發(fā)送一個信號

q.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作,。

其他模式

Python Queue模塊有三種隊列及構造函數(shù):

1,、Python Queue模塊的FIFO隊列先進先出,。 class queue.Queue(maxsize)

2、LIFO類似于堆,,即先進后出,。 class queue.LifoQueue(maxsize)

3、還有一種是優(yōu)先級隊列級別越低越先出來,。 class queue.PriorityQueue(maxsize ) 

謝謝閱讀,,著作權歸作者所有,如有侵權請聯(lián)系小編刪除,!

    本站是提供個人知識管理的網絡存儲空間,,所有內容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多