1. 程式人生 > >python 學習總結2 多進程

python 學習總結2 多進程

imp 交互 發送信息 bob res pip 子線程 for test

多進程:

我們什麽時候需要多進程呢?我們知道python的多線程,實際不是真實的多線程,它同一時間在一個cpu執行一個任務,它通過上下文的切換來讓我看起來是多並發的,

那麽如果我們想要真正實現多個任務在多個cpu上同時執行,我們就需要多進程的性質來幫忙了(python的多線程不適合cpu密集型的任務,適合io密集型的任務)。

import multiprocessing
import threading

def thread_run():
    print(threading.get_ident())
def run():
    print("ok")
    t=threading.Thread(target=thread_run(),)
    t.start()
if __name__=="__main__": for i in range(10): p=multiprocessing.Process(target=run,) p.start()

上端代碼體現了多進程用法其實就是在形式上與多線程是大同小異的!

通過學習多線程我們知道所有的線程都是有一個父線程

from multiprocessing import Process
import os


def info(title):
    print(title)
    #os.getppid 顯示父線程的id
    print(parent process:
, os.getppid()) #os.getid顯示子線程的id print(process id:, os.getpid()) print("\n\n") def f(name): info(\033[31;1mcalled from child process function f\033[0m) print(hello, name) if __name__ == __main__: info(\033[32;1mmain process line\033[0m) p = Process(target=f, args=(
bob,)) p.start()

通過上面的代碼,我們在主線程調用info顯示了 主線程相對的 父線程,與子線程,而且我們發現父線程就是pycharm本身,其子線程作為相對於這段代碼子線程的主線程,通過這段代碼我們了解了Python的主線程與子線程之間的關系

多進程Queue:

那麽我們如何實現主線程與子線程公用一塊數據呢,也就是我們怎麽才能實現兩個進程之間的交互呢?看下文

多進程的Queue與線程中的隊列是不同的,註意不能在多進程中調用線程的Queue因為每個線程都有各自占用一塊內存,多線程是共享一塊內存的,本質上是不同的

import multiprocessing
def f(qq):
    print("in child:",qq.qsize())
    qq.put([42, None, hello])
if __name__ == __main__:
    q = multiprocessing.Queue()
    q.put("test123")
    p = multiprocessing.Process(target=f, args=(q,))
    p.start()
    p.join()

多進程的pipes與manager:

我們的管道實際上就像socket 一樣 ,其實就是相互收發的過程

from multiprocessing import Process, Pipe


def f(conn):
    #在子線程發送信息
    conn.send([42, None, hello from child])
    conn.send([42, None, hello from child3])
    print("",conn.recv())
    conn.close()


if __name__ == __main__:
  #註意建立的順序,有兩個其實順序無所謂,註意後面的接受順序就好
    parent_conn, child_conn = Pipe()
    p = Process(target=f, args=(child_conn,))
    p.start()
    print("parent",parent_conn.recv())  # prints "[42, None, ‘hello‘]"
    print("parent",parent_conn.recv())  # prints "[42, None, ‘hello‘]"
    parent_conn.send(" from hshs")  # prints "[42, None, ‘hello‘]"
    p.join()
下面是manager的用法 ,實際上都類似,體現了兩個進程分享一些
from multiprocessing import Process, Manager
import os

def f(d, l):
    d[1] = 1
    d[2] = 2
    d["pid%s" %os.getpid()] = os.getpid()
    l.append(1)
    print(l,d)


if __name__ == __main__:
    with Manager() as manager:
        d = manager.dict()

        l = manager.list(range(5))

        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()
        l.append("from parent")
        print(d)
        print(l)

數據進行修改

python 學習總結2 多進程