python之路: 線程、進程和協程

進程和線程python

既然看到這一章,那麼你確定知道如今的系統都是支持「多任務」的操做,好比: Mac OS X,UNIX,Linux,Windows等。git

多任務:簡單地說就是同時運行多個任務。譬如:你能夠一邊看小電影,一邊用word寫感覺,在一邊錄製,這就是多任務,至少同時有3個任務正在運行。還有不少任務在後臺運行,只是桌面上沒有顯示而已。程序員

 如今,多核CPU已經很廣泛了,可是,即便在過去單核的時代,也是能夠執行多任務的。因爲CPU執行代碼都是順序執行的,那麼單核CPU是怎麼執行多任務的呢?答案就是:操做系統輪流讓各個任務交替執行,任務1執行0.01秒,任務2執行0.01秒,在切換到任務3上......這樣反覆下去。表面看都是交替執行的,可是,CPU的執行速度太快,因此咱們感受就像全部任務都在同時執行同樣。github

真正的同時執行多任務只能在多核CPU上實現,可是,任務數量遠遠多於CPU的核心數量,因此操做系統也會自動把不少任務輪流調度到每一個核心上執行。算法

對於操做系統來講,一個任務就是一個進程(Process)有些進程還不止同時幹一件事,好比word,它能夠同時進行打字、拼寫檢查,打印等事情 。在一個進程內部,要同時幹多件事,因此,一個進程至少有一個線程。固然,像word這種複雜的進程能夠有多個線程,多個線程能夠同時執行,多線程的執行方式和多進程是同樣的,也是由操做系統在多個線程以前快速的切換,讓每個線程都在短暫地交替運行,看起來就像同時執行同樣。固然,真正地同時支持多線程須要多核CPU纔可能實現。編程

前面寫的全部Python程序,都是執行單任務的進程,也就是隻有一個線程。若是要同時執行多個任務,請繼續往下看。服務器

有兩種解決方案:多線程

一種是啓動多個進程,每一個進程雖然只有一個線程,但多個進程能夠一塊執行多個任務。併發

還有一種方法是啓動一個進程,在一個進程內啓動多個線程,這樣,多個線程也能夠一塊執行多個任務。app

第三個方法就是啓動多個進程,每一個進程在啓動多個線程,這樣同時執行的任務就更多了,固然這中模型更復雜,實際不多采用。

總結如下就是,多任務的實現有3種方式:

  • 多進程模式
  • 多線程模式
  • 多進程+多線程模式

 同時支持多個任務一般各個任務之間並非沒有關聯的,二是須要相互通訊和協調,有時,任務1必須暫停等待任務2完成才能繼續執行,有時,任務3和任務4又不能同時執行,因此,多進程和多線程的程序的複雜度要遠遠高於咱們前面寫的單進程單線程的程序。

由於複雜度高,調試困難,因此,不是無可奈何,咱們也不想編寫多任務。可是,有不少時候,沒有多任務還真不行。Python既支持多進程,又支持多線程,咱們會討論如何編寫這兩種多任務程序。

Python 多進程

 要讓Python程序實現多進程,咱們要先了解一些操做系統的相關知識。

Unix/Linux操做系統提供了一個fork()系統調用,它很是特殊。普通的函數調用,調用一次,返回一次,可是fork()調用一次,返回兩次,由於操做系統自動把當前進程(稱爲父進程)複製了一份(稱爲子進程),而後,分別在父進程和子進程內返回。

子進程永遠返回0,而父進程返回子進程的ID。這樣作的理由是,一個父進程能夠fork出不少子進程,因此,父進程要記下每個子進程的ID,而子進程只須要調用getppid()就能夠拿到父進程的ID。

Python的os模塊封裝了常見的系統調用,其中就包括fork,能夠在Python程序中輕鬆建立子進程:

import os

print( ' Process (%s) start... ' % os.getpid())
#  Only works on Unix/Linux/Mac:
pid = os.fork()
if pid == 0:
     print( ' I am child process (%s) and my parent is %s. ' % (os.getpid(), os.getppid()))
else:
     print( ' I (%s) just created a child process (%s). ' % (os.getpid(), pid))  

 運行結果以下:

Process (876) start...
I (876) just created a child process (877).
I am child process (877)  and my parent  is 876.

 因爲Windows沒有fork調用,上面的代碼不能在Windows上運行。因爲Mac系統是基於BSD(Unix的一種)內核,因此,在Mac下運行是沒有問題的,推薦是用Mac下學習Python!

有了fork調用,一個進程在接到新任務時就能夠複製出一個子進程來處理新任務,常見才Apache服務器就是由附近吃監聽端口,每當有新的http請求時,就fork出子進程來處理新的http請求。

multiprocessing

from multiprocessing import Process, Queue
import os, time, random, threading
def fool(i):
    print  ' say hi ',i
if __name__ ==  ' __main__ ':
     for i  in range( 1000):
        i = Queue()
        p = Process(target=fool,args=(i,))
        p.start()

執行結果:

say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hisay hi  <multiprocessing.queues.Queue  object at  0x00000000022C52B0><multiprocessing.queues.Queue  object at  0x00000000023D52B0>

say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hisay hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
 <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023752B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023052B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023452B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022D52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023C52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023352B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023252B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022F52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023852B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023552B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000024152B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023A52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023952B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000022B52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023E52B0>
say hi <multiprocessing.queues.Queue  object at  0x00000000023652B0>
View Code

若是你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。因爲Windows沒有fork調用,而Python是跨平臺的,天然應該提供一個跨平臺的多進程支持。multiprocessing模塊就是跨平臺版本的多進程模塊。

multiprocessing模塊提供了一個process類來表明一個進程對象,下面的例子演示了啓動一個子進程並等待其結束:

# !/usr/bin/env  python
#
 --*--coding:utf-8 --*--
from multiprocessing  import Process
import os

#  子進程要執行的代碼
def run_proc(name):
     print( ' Run child process %s (%s)... ' % (name, os.getpid()))

if  __name__== ' __main__ ':
     print( ' Parent process %s. ' % os.getpid())
    p = Process(target=run_proc, args=( ' test ',))
     print( ' Child process will start. ')
    p.start()
    p.join()
     print( ' Child process end. ')

 執行結果以下:

Parent process 8608.
Child process will start.
Run child process test (8752)...
Child process end.

 建立子進程時,只須要傳入一個執行函數和函數的參數,建立一個process實例,用start()方法啓動,這樣建立進程比fork()還要簡單。

join()方法能夠等待子進程結束後再繼續往下運行,一般用於進程間的同步。

POOL

若是要啓動大量的子進程,能夠用進程池的方式批量建立子進程:

# !/usr/bin/env  python
#
 --*--coding:utf-8 --*--
from multiprocessing  import Pool
import os, time, random

def long_time_task(name):
     print( ' Run task %s (%s)... ' % (name, os.getpid()))
    start = time.time()
    time.sleep(random.random() * 3)
    end = time.time()
     print( ' Task %s runs %0.2f seconds. ' % (name, (end - start)))

if  __name__== ' __main__ ':
     print( ' Parent process %s. ' % os.getpid())
    p = Pool(4)
     for i  in range(5):
        p.apply_async(long_time_task, args=(i,))
     print( ' Waiting for all subprocesses done... ')
    p.close()
    p.join()
     print( ' All subprocesses done. ')

 執行結果:

Parent process 9052.
Waiting  for all subprocesses done...
Run task 0 (7832)...
Run task 1 (8388)...
Run task 2 (8224)...
Run task 3 (9272)...
Task 1 runs 1.00 seconds.
Run task 4 (8388)...
Task 2 runs 1.19 seconds.
Task 0 runs 1.85 seconds.
Task 3 runs 2.01 seconds.
Task 4 runs 1.65 seconds.
All subprocesses done.
執行結果

 代碼解讀:

對Pool對象調用join()方法會等待全部子進程執行完畢,調用join()以前必須先調用close(),調用close()以後就不能繼續添加新的Process了。

請注意輸出的結果,task 0,1,2,3是當即執行的,而task4是要等待前面某個task完成後才執行,這是由於pool的默認大小在個人電腦是上4,所以,最多同時執行4個進程。這是pool有意設計的限制,並非操做系統的限制。若是改爲:

p = Pool(5)

 就能夠同時跑5個進程。

因爲Pool的默認大小是CPU的核數,若是你的電腦擁有8核CPU,你要提交至少9個子進程才能看到上面的等待效果。

子進程

不少時候,子進程並非自身,二是一個外部進程。咱們建立了子進程後,還須要控制子進程的輸入和輸出。

subprocess模塊可讓咱們很是方便地啓動一個子進程,而後控制其輸入輸出。

 下面的例子演示瞭如何在Python代碼中運行命令nslookup www.python.org,這和命令知己運行的效果是同樣的:

# !/usr/bin/env  python
#
 --*--coding:utf-8 --*--
import subprocess
print('$ nslookup www.python.org')
r = subprocess.call(['nslookup', 'www.python.org'])
print('Exit code:', r)

 運行結果:

$ nslookup www.python.org
Server:        192.168.19.4
Address:    192.168.19.4 # 53

Non-authoritative answer:
www.python.org    canonical name = python.map.fastly.net.
Name:    python.map.fastly.net
Address: 199.27.79.223

Exit code: 0

 若是子進程還須要輸入,則能夠經過communicate()方法輸入:

import subprocess

print( ' $ nslookup ')
p = subprocess.Popen([ ' nslookup '], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, err = p.communicate(b ' set q=mx\npython.org\nexit\n ')
print(output.decode( ' utf-8 '))
print( ' Exit code: ', p.returncode)

 上面的代碼至關於在命令執行nslookup,而後手動輸入:

set q=mx
python.org
exit

 運行結果以下:

$ nslookup
Server:        192.168.19.4
Address:    192.168.19.4 # 53

Non-authoritative answer:
python.org    mail exchanger = 50 mail.python.org.

Authoritative answers can be found  from:
mail.python.org    internet address = 82.94.164.166
mail.python.org    has AAAA address 2001:888:2000:d::a6


Exit code: 0

 進程間通訊

Process之間確定是須要通訊的,操做系統提供了不少機制來實現進程間的通訊。Python的multiprocessing模塊包裝了底層的機制,提供看Queue、Pipes等多種方式來交換數據。

咱們以Queue爲例,在父進程中建立兩個子進程,一個往Queue裏寫數據,一個從Queue裏讀數據:

# !/usr/bin/env  python
#
 --*--coding:utf-8 --*--
from multiprocessing  import Process, Queue
import os, time, random

#  寫數據進程執行的代碼:
def write(q):
     print( ' Process to write: %s ' % os.getpid())
     for value  in [ ' A '' B '' C ']:
         print( ' Put %s to queue... ' % value)
        q.put(value)
        time.sleep(random.random())

#  讀數據進程執行的代碼:
def read(q):
     print( ' Process to read: %s ' % os.getpid())
     while True:
        value = q.get(True)
         print( ' Get %s from queue. ' % value)

if  __name__== ' __main__ ':
     #  父進程建立Queue,並傳給各個子進程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
     #  啓動子進程pw,寫入:
    pw.start()
     #  啓動子進程pr,讀取:
    pr.start()
     #  等待pw結束:
    pw.join()
     #  pr進程裏是死循環,沒法等待其結束,只能強行終止:
    pr.terminate()

 運行結果:

Process to write: 9188
Put A to queue...
Process to read: 9540
Get A  from queue.
Put B to queue...
Get B  from queue.
Put C to queue...
Get C  from queue.

 在Unix/Linux下,multiprocessing模塊封裝了fork()調用,使咱們不須要關注fork()的細節。因爲Windows沒有fork調用,所以,multiprocessing須要「模擬」出fork的效果,父進程全部Python對象都必須經過pickle失敗了。

進程數據共享

進程各自持有一份數據,默認沒法共享數據

#!/usr/bin/env  python
# --*--coding:utf- 8 --*--
from multiprocessing import Process
from multiprocessing import Manager

import time

li = []

def foo(i):
    li.append(i)
    print  ' say hi ',li
if __name__ ==  ' __main__ ':
     for i  in range( 10):
        p = Process(target=foo,args=(i,))
        p.start()

    print  ' ending ',li

print  ' ending ',li
進程間默認沒法數據共享

執行結果

ending []
say hi [ 1]
ending []
say hi [ 2]
ending []
say hi [ 0]
ending []
say hi [ 3]
ending []
say hi [ 6]
ending []
say hi [ 5]
ending []
say hi [ 4]
ending []
ending []
ending []
say hi [ 7]
ending []
say hi [ 8]
ending []
say hi [ 9]
執行結果

共享實例一

#!/usr/bin/env  python
# --*--coding:utf- 8 --*--
from multiprocessing import Process,Array
temp = Array( ' i ', [ 11, 22, 33, 44])

def Foo(i):
    temp[i] =  100+i
     for item  in temp:
        print i, ' -----> ',item
if __name__ ==  ' __main__ ':
     for i  in range( 4):
        p = Process(target=Foo,args=(i,))
        p.start()
Array

 執行結果:

1 ----->  11
1 ----->  101
1 ----->  33
1 ----->  44
0 ----->  100
0 ----->  22
0 ----->  33
0 ----->  44
2 ----->  11
2 ----->  22
2 ----->  102
2 ----->  44
3 ----->  11
3 ----->  22
3 ----->  33
3 ----->  103
Array結果

實例二:manage.dict()共享數據

from multiprocessing import Process,Manager
 
manage = Manager()
dic = manage.dict()
 
def Foo(i):
    dic[i] =  100+i
    print dic.values()
 
for i  in range( 2):
    p = Process(target=Foo,args=(i,))
    p.start()
    p.join()
manage.dict()

類型對應表

' c ': ctypes.c_char,   ' u ': ctypes.c_wchar,
' b ': ctypes.c_byte,   ' B ': ctypes.c_ubyte,
' h ': ctypes.c_short,  ' H ': ctypes.c_ushort,
' i ': ctypes.c_int,    ' I ': ctypes.c_uint,
' l ': ctypes.c_long,   ' L ': ctypes.c_ulong,
' f ': ctypes.c_float,  ' d ': ctypes.c_double
View Code

 當建立進程時(非使用時),共享數據會被拿到子進程中,當進程中執行完畢後,在賦值給原值。

#!/usr/bin/env  python
# --*--coding:utf- 8 --*--
from multiprocessing import Process, Array, RLock

def Foo( lock,temp,i):
     """
    將第0個數加100
     """
     lock.acquire()
    temp[ 0] =  100+i
     for item  in temp:
        print i, ' -----> ',item
     lock.release()

lock = RLock()
temp = Array( ' i ', [ 11223344])

for i  in range( 20):
    p = Process(target=Foo,args=( lock,temp,i,))
    p.start()
進程鎖實例

 進程池

進程池內部維護一個進程序列,當使用時,則去進程池中獲取一個進程,若是進程池序列中沒有可供使用的進程,那麼程序就會等待,知道進程池中有可用進程爲止。

進程池中有兩個方法:

 

  • apply
  • apply_async 

 

#!/usr/bin/env  python
# --*--coding:utf- 8 --*--
from  multiprocessing import Process,Pool
import time

def Foo(i):
    time.sleep( 2)
     return i+ 100

def Bar(arg):
    print arg

pool = Pool( 5)
# print pool.apply(Foo,( 1,))
#print pool.apply_async(func =Foo, args=( 1,)). get()
for i  in range( 10):
    pool.apply_async(func=Foo, args=(i,),callback=Bar)

print  ' end '
pool.close()
pool.join()#進程池中進程執行完畢後再關閉,若是註釋,那麼程序直接關閉。

Python 多線程 

 多任務能夠由多進程完成,也能夠由一個進程內的多線程完成。

 咱們前面提到了進程是由若干進程組成的,一個進程至少有一個線程。

因爲線程是操做系統直接支持的執行單元,所以,高級語言一般都內置多線程的支持,Python也不例外,而且,Python的線程是真正的Posix Thread,而不是模擬出來的線程。

Python的標準庫提供了兩個模塊:_thread和threading,_thread是低級模塊,threading是高級模塊,對_thread進行了封裝。絕大多數狀況下,咱們只須要使用threading這個高級模塊。

啓動一個線程就是把一個函數傳入並建立Thread實例,而後調用start()開始執行:

# !/usr/bin/env  python
#
 --*--coding:utf-8 --*--
import time, threading

#  新線程執行的代碼:
def loop():
     print( ' thread %s is running... ' % threading.current_thread().name)
    n = 0
     while n < 5:
        n = n + 1
         print( ' thread %s >>> %s ' % (threading.current_thread().name, n))
        time.sleep(1)
     print( ' thread %s ended. ' % threading.current_thread().name)

print( ' thread %s is running... ' % threading.current_thread().name)
t = threading.Thread(target=loop, name= ' LoopThread ')
t.start()
t.join()
print( ' thread %s ended. ' % threading.current_thread().name)
實例一

來一個反的

# !/usr/bin/env python
#
 -*- coding:utf-8 -*-
 
import threading
import time

def show(arg):
    time.sleep(1)
     print  ' thread '+str(arg)

for i  in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print  ' main thread stop '
實例二

執行結果:

thread MainThread  is running...
thread LoopThread  is running...
thread LoopThread >>> 1
thread LoopThread >>> 2
thread LoopThread >>> 3
thread LoopThread >>> 4
thread LoopThread >>> 5
thread LoopThread ended.
thread MainThread ended.
實例一
main thread stop
thread3thread0thread4thread1thread5thread2





thread7thread9

 thread8thread6
實例二

實例一: 

 因爲任何進程默認就會啓動一個線程,咱們把該線程稱爲主線程,主線程又能夠啓動新的線程,Python的threading模塊有個current_thread()函數,它永遠返回當前線程的實例。主線程實例的名字叫MainThread,子線程的名字在建立時指定,咱們用LoopThread命名子線程。名字僅僅在打印時用來顯示,徹底沒有其它意義,若是不起名字Python就自動給線程命名爲Thread-1,Thread-2........

實例二:

上述代碼建立了10個「前臺」線程,而後控制器就交給了CPU,CPU根據指定算法進行調度,分片執行指令。

更多方法:

  • start 線程準備就緒,等待CPU調度
  • setName 爲線程設置名稱
  • getName 獲取線程名稱
  • setDaemon   設置爲後臺線程或前臺線程(默認)
若是是後臺線程,主線程執行過程當中,後臺線程也在進行,主線程執行完畢後,後臺線程不論成功與否,均中止

若是是前臺線程,主線程執行過程當中,前臺線程也在進行,主線程執行完畢後,等待前臺線程也執行完畢後,程序中止。

  • join  逐個執行每一個線程,執行完畢後繼續往下執行,該方法使得多線程變得無心義
  • run 線程被CPU調度後執行Thread類對象的run方法

線程鎖(Lock

多線程和多進程最大的不一樣之處在於,多進程中,同一個變量,各自有一份拷貝存在於每一個進程中,相互之間不受影響,而多線程中,全部變量都由全部線程共享,因此,任何一個變量均可以被任何一個線程修改,所以,線程之間共享數據最大的危險在於多個線程同時改一個變量,把內容給改亂了。

來看看多個線程同時操做一個變量怎麼把內容給改亂了:

# !/usr/bin/env python
#
 -*- coding:utf-8 -*-
import time, threading

#  假定這是你的銀行存款:
balance = 0

def change_it(n):
     #  先存後取,結果應該爲0:
     global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
     for i  in range(100000):
        change_it(n)

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)
實例一
#!/usr/bin/env python
# -*- coding:utf- 8 -*-
import threading
import time

gl_num =  0

def show(arg):
     global gl_num
    time.sleep( 1)
    gl_num += 1
    print gl_num

for i  in range( 10):
    t = threading.Thread(target=show, args=(i,))
    t.start()

print  ' main thread stop '
實例二

實例一 咱們定義了一個共享變量balance,初始值爲0,而且啓動兩個線程,先存後取,理論上結果應該爲0,可是,因爲線程的調度是由操做系統決定是,當t一、t2交替執行時,只要循環次數足夠多,balance的結果就不必定是0了。

緣由是由於高級語言的一條語句在CPU執行時是若干條語句,即便一個簡單的計算:

balance = balance + n

 也分兩步:

 一、計算balance + n ,存入臨時變量中;

 二、將臨時變量的值賦給balance。

也就是能夠當作:

x = balance + n
balance = x

 因爲x是局部變量,兩個線程各自都有本身的X,當代碼正常執行時:

初始值 balance = 0

t1: x1 = balance + 5  #  x1 = 0 + 5 = 5
t1: balance = x1      #  balance = 5
t1: x1 = balance - 5  #  x1 = 5 - 5 = 0
t1: balance = x1      #  balance = 0

t2: x2 = balance + 8  #  x2 = 0 + 8 = 8
t2: balance = x2      #  balance = 8
t2: x2 = balance - 8  #  x2 = 8 - 8 = 0
t2: balance = x2      #  balance = 0

結果 balance = 0

 可是t1和t2是交替運行的,若是操做系統如下面的順序執行t一、t2:

初始值 balance = 0

t1: x1 = balance + 5   #  x1 = 0 + 5 = 5

t2: x2 = balance + 8   #  x2 = 0 + 8 = 8
t2: balance = x2       #  balance = 8

t1: balance = x1       #  balance = 5
t1: x1 = balance - 5   #  x1 = 5 - 5 = 0
t1: balance = x1       #  balance = 0

t2: x2 = balance - 8   #  x2 = 0 - 8 = -8
t2: balance = x2    #  balance = -8

結果 balance = -8

 究其緣由,是由於修改balance須要多條語句,而執行這幾條語句時,線程可能中斷,從而致使多個線程把同一個對象的內容改亂了。

兩個線程同時一存一取,就可能致使餘額不對,你確定不但願你的銀行存款莫名其妙地變成了負數,因此,咱們必須確保一個線程在修改balance的時候,別的線程必定不能改。

若是咱們要確保balance計算正確,就要給change_it()上一把鎖,當某個線程開始執行change_it()時,咱們說,該鎖之後才能改。因爲鎖只有一個,不管多少線程,同一時刻最多隻有一個線程持有該鎖,因此,不會形成修改的衝突。建立一個鎖就是經過threading.Lock()來實現:

balance = 0
lock = threading.Lock()

def run_thread(n):
     for i  in range(100000):
         #  先要獲取鎖:
        lock.acquire()
         try:
             #  放心地改吧:
            change_it(n)
         finally:
             #  改完了必定要釋放鎖:
            lock.release()
#!/usr/bin/env python
# -*- coding:utf- 8 -*-
import threading
import time
   
gl_num =  0

lock = threading.RLock()

def Func():
     lock.acquire()#獲取鎖
     global gl_num
    gl_num += 1
    time.sleep( 1)
    print gl_num
     lock.release()#釋放鎖

for i  in range( 10):
    t = threading.Thread(target=Func)
    t.start()
實例二

 當多個線程同時執行lock.acquire()時,只有一個線程能成功地獲取鎖,而後繼續執行代碼,其餘線程就繼續等待直到得到鎖爲止。

 得到鎖的線程用完後必定要釋放鎖,不然那些等待的 線程將永遠等待下去,成爲死進程。因此咱們用try...finally來確保鎖必定會被釋放。

鎖的好處就是確保了某段關鍵代碼只能由一個線程從頭至尾完整地執行,壞處固然也有不少,首先是阻止了多線程併發執行,包含鎖的某段代碼實際上只能以單線程模式執行,笑臉就大大地降低了。其次,因爲能夠存在多個鎖,不一樣的線程持有不一樣的鎖,並試圖獲取對方的鎖時,可能會形成死鎖,致使多個線程所有掛起,即不能執行,也沒法結束,只能靠操做系統強制終止。

事件

Python線程的事件用於主線程控制其餘線程的執行,事件主要提供了三個方法set、wait、clear。

事件的處理機制:全局定義了一個「Flag」,若是「Flag」值爲False,那麼當程序執行even.wait方法時就會阻塞,若是「Flag」值爲True,那麼event.wait方法時便再也不阻塞。 

  • clear:將「Flag」設置爲False
  • set:將「Flag」設置爲True
#!/usr/bin/env python
# -*- coding:utf- 8 -*-
import threading


def  do( event):
    print  ' start '
     event.wait()
    print  ' execute '


event_obj = threading.Event()
for i  in range( 10):
    t = threading.Thread(target= do, args=(event_obj,))
    t.start()

event_obj.clear()
inp = raw_input( ' input: ')
if inp ==  ' true ':
    event_obj. set()

多核CPU

若是你不幸擁有一個多核CPU,你確定在想,多核應該能夠同時執行多個線程。

若是寫一個死循環的話,會出現什麼狀況呢?

打開Mac OS X的Activity Monitor,或者Windows的Task Manager,均可以監控某個進程的CPU使用率。

 咱們能夠監控到一個死循環線程會100%佔用一個CPU。

若是有兩個死循環線程,在多核CPU中,能夠監控到會佔用200%的CPU,也就是佔用兩個CPU核心。

要想把N核CPU的核心所有跑滿,就必須啓動N個死循環線程。

試試用Python寫一個死循環:

import threading, multiprocessing

def loop():
    x = 0
     while True:
        x = x ^ 1

for i  in range(multiprocessing.cpu_count()):
    t = threading.Thread(target=loop)
    t.start()

 啓動與CPU核心數量相同的N個線程,在4核CPU上能夠監控到CPU佔用率僅有102%,也就是僅使用了一核。可是用C、C++或Java來改寫相同的死循環,直接能夠把所有核心跑滿,4核就跑到400%,8核就跑到800%,爲何Python不行呢?

由於Python的線程雖然是真正的線程,但解釋器執行代碼時,有一個GIL鎖:Global Interpreter Lock,任何Python線程執行前,必須先得到GIL鎖,而後,每執行100條字節碼,解釋器就自動釋放GIL鎖,讓別的線程有機會執行。這個GIL全局鎖實際上把全部線程的執行代碼都上了鎖,因此,多線程在Python中只能交替執行,即便100個線程跑在100核CPU上,也只能用到1核。

GIL是Python解釋器設計的歷史遺留問題,一般咱們用的解釋器是官方實現的CPython,要真正利用多核,除非重寫一我的不帶GIL的解釋器。

因此,在Python中,可使用多線程,但不要期望能有效利用多核。若是必定要經過多線程利用多核,那隻能經過C擴展來實現,不過這樣就失去了Python簡單易用的特色。

不過,也不用過於擔憂,Python雖然不能利用多線程實現多核任務,但能夠經過多進程實現多核任務。多個Python進程有各自獨立的GIL鎖,互不影響。

協程

 線程和進程的操做是由程序觸發系統接口,最後的執行者是系統;協程的操做則是程序員。

協程存在的意義:對於多線程應用,CPU經過切片的方式來切換線程間的執行,線程切換時須要耗時(保存狀態,下次繼續)。協程,則只使用一個線程,在一個線程中規定某個代碼塊執行順序。

協程的使用場景:當程序中存在大量不須要CPU的操做時(IO),適用於協程;

greenlet

#!/usr/bin/env python
# -*- coding:utf- 8 -*-
 
 
from greenlet import greenlet
 
 
def test1():
    print  12
    gr2. switch()
    print  34
    gr2. switch()
 
 
def test2():
    print  56
    gr1. switch()
    print  78
 
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1. switch()
gevent
import gevent
 
def foo():
    print( ' Running in foo ')
    gevent.sleep( 0)
    print( ' Explicit context switch to foo again ')
 
def bar():
    print( ' Explicit context to bar ')
    gevent.sleep( 0)
    print( ' Implicit context switch back to bar ')
 
gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
])

 遇到IO操做自動切換:

from gevent import monkey; monkey.patch_all()
import gevent
import urllib2

def f(url):
    print( ' GET: %s ' % url)
    resp = urllib2.urlopen(url)
    data = resp.read()
    print( ' %d bytes received from %s. ' % (len(data), url))

gevent.joinall([
        gevent.spawn(f,  ' https://www.python.org/ '),
        gevent.spawn(f,  ' https://www.yahoo.com/ '),
        gevent.spawn(f,  ' https://github.com/ '),
])
View Code

 總結:

要實現跨平臺的多進程,可使用multiprocessing模塊。

進程間通訊是經過Queue、pipes等實現的。 

線程是最小的執行單元,而進程由至少一個線程組成。如何調度進程和線程,徹底由操做系統決定,程序本身不能決定何時執行,執行多久時間。

多進程和多線程的程序涉及到同步,數據共享的問題,編寫起來更復雜。 

多線程編程,模型複雜,容易發生衝突,必須用鎖加以隔離,同時,又要當心死鎖發生。

Python解釋器因爲設計時有GIL全局鎖,致使了多線程沒法利用多核。多線程的併發在Python中就是一個美麗的夢。 

相關文章
相關標籤/搜索