1. 程式人生 > >python 學習第二十五天(程序的呼叫,程序池)

python 學習第二十五天(程序的呼叫,程序池)

  • 程序的呼叫
    • 方法一:
from multiprocessing import Process
import time
def f(name):
    time.sleep(1)
    print('hello', name,time.ctime())

if __name__ == '__main__':
    p_list=[]
    for i in range(3):
        p = Process(target=f, args=('alvin',))
        p_list.append(p)
        p.start()
    for
i in p_list: p.join() print('end')
    • 方法二
from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self):
        super(MyProcess, self).__init__()
        #self.name = name

    def run(self):
        time.sleep(1)
        print ('hello'
, self.name,time.ctime()) if __name__ == '__main__': p_list=[] for i in range(3): p = MyProcess() p.start() p_list.append(p) for p in p_list: p.join() print('end')
  • Process 類
    構造方法:
    Process([group [, target [, name [, args [, kwargs]]]]])

      group: 執行緒組,目前還沒有實現,庫引用中提示必須是None;
      target: 要執行的方法;
      name: 程序名;
      args/kwargs: 要傳入方法的引數。
    例項方法:

      is_alive():返回程序是否在執行。

      join([timeout]):阻塞當前上下文環境的程序程,直到呼叫此方法的程序終止或到達指定的timeout(可選引數)。

      start():程序準備就緒,等待CPU排程

      run():strat()呼叫run方法,如果例項程序時未制定傳入target,這star執行t預設run()方法。

       terminate():不管任務是否完成,立即停止工作程序
    屬性:

      daemon:和執行緒的setDeamon功能一樣

      name:程序名字。

      pid:程序號。

  • 程序間的通訊

    • 程序佇列
from multiprocessing import Process, Queue
import queue

def f(q,n):
    #q.put([123, 456, 'hello'])
    q.put(n*n+1)
    print("son process",id(q))

if __name__ == '__main__':
    q = Queue()  #try: q=queue.Queue()
    print("main process",id(q))

    for i in range(3):
        p = Process(target=f, args=(q,i))
        p.start()

    print(q.get())
    print(q.get())
    print(q.get())
    • 管道
from multiprocessing import Process, Pipe

def f(conn):
    conn.send([12, {"name":"yuan"}, 'hello'])
    response=conn.recv()
    print("response",response)
    conn.close()
    print("q_ID2:",id(child_conn))

if __name__ == '__main__':

    parent_conn, child_conn = Pipe()
    print("q_ID1:",id(child_conn))
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())   # prints "[42, None, 'hello']"
    parent_conn.send("你好!")
    p.join()
    • Managers

Queue和pipe只是實現了資料互動,並沒實現資料共享,即一個程序去更改另一個程序的資料。

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 list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array. For example:

from multiprocessing import Process, Manager

def f(d, l,n):
    d[n] = '1'
    d['2'] = 2
    d[0.25] = None
    l.append(n)
    #print(l)

    print("son process:",id(d),id(l))

if __name__ == '__main__':

    with Manager() as manager:

        d = manager.dict()

        l = manager.list(range(5))

        print("main process:",id(d),id(l))

        p_list = []

        for i in range(10):
            p = Process(target=f, args=(d,l,i))
            p.start()
            p_list.append(p)

        for res in p_list:
            res.join()

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

程序池中有兩個方法:

apply
apply_async

from  multiprocessing import Process,Pool
import time,os

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

def Bar(arg):

    print(os.getpid())
    print(os.getppid())
    print('logger:',arg)
if __name__=='__main__':
    pool = Pool(5)

    Bar(1)
    print("----------------")

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

    pool.close()#這兩行是必須的,且順序不能顛倒
    pool.join()#
    print('end')