python進程編程

來源:互聯網
上載者:User

標籤:簡易   recv   log   sim   sem   沒有   詳解   inux   join   

 多進程multiprocess模組

multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads. Due to this, the multiprocessing module allows the programmer to fully leverage multiple processors on a given machine. It runs on both Unix and Windows.

這個模組的文法結構與threading模組基本相似。

尋找到一個多進程的部落格串連:https://www.cnblogs.com/Mr-Murray/p/9026955.html

from  multiprocessing import Processimport timeimport osdef info():    print("\033[35;1mThe time is %s\033[0m" % time.ctime())    print("The parent is %s; The Child process is %s" % (os.getppid(), os.getpid()))if __name__  == "__main__":    for i in range(10):        p = Process(target=info)        p.start()        p.join()

這段代碼和之前用threading模組建立的多線程並沒有任何的區別,但是如果在windows系統上執行時,必須加上if __name__ == "__main__":語句,原因如下:

在Windows作業系統中由於沒有fork(linux作業系統中建立進程的機制),在建立子進程的時候會自動 import 啟動它的這個檔案,
而在 import 的時候又執行了整個檔案。因此如果將process()直接寫在檔案中就會無限遞迴建立子進程報錯。所以必須把建立子
進程的部分使用if __name__ ==‘__main__’ 判斷保護起來,import 的時候 ,就不會遞迴運行了。

以執行個體化的方式產生進程:
import os, timefrom multiprocessing import Processclass Myprocess(Process):    def __init__(self):        super(Myprocess, self).__init__()    def run(self):        print("\033[35;1mThe time is %s\033[0m" % time.ctime())        print("The parent is %s; The Child process is %s" % (os.getppid(), os.getpid()))if __name__ == "__main__":    p = Myprocess()    p.start()
#在調用p.start的時候,會自動執行類中的run方法,run方法是必不可少的。和threading類中的Thread中的run方法一樣。

進程中的守護進程和threading模組中的守護線程是同一個意思,主進程結束的時候,子進程也會隨之結束。

import os, timefrom multiprocessing import Processdef fun1():    print("starting %s".center(50,"-") % time.ctime())    time.sleep(3)    print("Stopping %s".center(50,"-") % time.ctime())if __name__ == "__main__":    p = Process(target=fun1)    p.daemon = True    p.start()    time.sleep(1)--------------------------------------------------------------------------子進程中是要執行3s的,但主進程中只執行了1s,設定了守護進程之後,主進程結束,不管子進程的狀態,子進程都要退出

利用多進程實現簡易的socket並發串連。

server端代碼:import socket, timefrom multiprocessing import Processdef handle(conn,addr):    print("The connection is from %s at %s port" % addr)    conn.send(b"Hello world")    data = conn.recv(1024)    conn.send(data)if __name__ == "__main__":    HOST = "localhost"    PORT = 51423    ADDR = (HOST, PORT)    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.bind(ADDR)    s.listen(5)    while True:        conn, addr = s.accept()        p = Process(target=handle, args=(conn,addr)) # 進程間的資料是不共用的,因此需要把coon作為參數傳遞        p.start()    s.close()client端代碼:import socketHOST = "localhost"PORT = 51423ADDR = (HOST, PORT)s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(ADDR)data = s.recv(1024)print(data.decode())while True:    info = input(">>>: ")    s.send(info.encode())    data = s.recv(1024)    print(data.decode())

注意:

進程之間的資料是彼此之間不能互相訪問的,因此conn必須作為參數傳遞。

進程之間的通訊該怎麼做?

進程中的隊列和管道:
from multiprocessing import Process, Queuefrom time import sleepimport random# 利用進程寫一個產生消費者模型,# 產生者向隊列插入一個隨機數,消費者取出隊列中的一個數值def productor(q):    while True:        sleep(0.3)        print("store an num")        q.put(random.randint(1,100))def consumer(q):    while True:        sleep(0.2)        print("Getting an num")        q.get()if __name__ == "__main__":    q = Queue()    proc1 = Process(target=productor, args=(q,))    proc2 = Process(target=consumer, args=(q,))    proc1.start()    proc2.start()

這隻是一個簡易模型,來說明隊列在進程之間的通訊。

這裡的隊列用法和線程中隊列用法基本相同,只是一個用於進程通訊,一個用於線程通訊。

管道

管道的簡單實用:

 

from multiprocessing import Process, Pipedef f(conn):    conn.send("Hello world")    conn.close()if __name__ == ‘__main__‘:    parent_conn, child_conn = Pipe()    p = Process(target=f, args=(child_conn,))    p.start()    print(parent_conn.recv())    p.join()
manager

Manager()返回的manager對象控制了一個server進程,此進程包含的python對象可以被其他的進程通過proxies來訪問。從而達到多進程間資料通訊且安全。

 

A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.

A manager returned by Manager() will support types listdictNamespaceLockRLockSemaphoreBoundedSemaphoreConditionEventBarrierQueueValue and Array.

一個簡單實用的執行個體:

 

from multiprocessing import Process, Managerimport randomdef f(list):    list.append(random.randint(0,100))    print(list)if __name__ == "__main__":    p_list = []    with  Manager() as manager:        l = manager.list()        for i in range(10):            p = Process(target=f,args=(l,))            p.start()            p_list.append(p)        for res in p_list:            res.join()

 

每一個進程給列表中添加一個資料,執行結果如下:

[95]
[95, 25]
[95, 25, 31]
[95, 25, 31, 70]
[95, 25, 31, 70, 9]
[95, 25, 31, 70, 9, 17]
[95, 25, 31, 70, 9, 17, 96]
[95, 25, 31, 70, 9, 17, 96, 71]
[95, 25, 31, 70, 9, 17, 96, 71, 96]
[95, 25, 31, 70, 9, 17, 96, 71, 96, 3]

進程池:

進程池內部維護一個進程式列,當使用時,則去進程池中擷取一個進程,如果進程池序列中沒有可供使用的進進程,那麼程式就會等待,直到進程池中有可用進程為止。

from  multiprocessing import Process, Poolimport timedef Foo(i):    time.sleep(2)    return i + 100def Bar(arg):    print(‘-->exec done:‘, arg)if __name__ == "__main__":    pool = Pool(5)    for i in range(10):        pool.apply_async(func=Foo, args=(i,), callback=Bar)        # pool.apply(func=Foo, args=(i,))    print(‘end‘)    pool.close()    pool.join()

注意:其中在調用apply_async時候使用了callback回呼函數

進程池詳解,看到的一片博文:https://www.cnblogs.com/qiangyuge/p/7455814.html

 

python進程編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.