久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      Python多進程知識點總結(jié)

      本篇文章給大家?guī)砹岁P(guān)于python的相關(guān)知識,其中主要介紹了關(guān)于多進程的相關(guān)內(nèi)容,包括了什么是多進程、進程的創(chuàng)建、進程間同步、進程池等等,下面一起來看一下,希望對大家有幫助。

      Python多進程知識點總結(jié)

      推薦學習:python視頻教程

      一、什么是多進程?

      1. 進程

      程序:例如xxx.py這是程序,是一個靜態(tài)的

      進程:一個程序運行起來后,代碼+用到的資源 稱之為進程,它是操作系統(tǒng)分配資源的基本單元。不僅可以通過線程完成多任務(wù),進程也是可以的

      2. 進程的狀態(tài)

      工作中,任務(wù)數(shù)往往大于cpu的核數(shù),即一定有一些任務(wù)正在執(zhí)行,而另外一些任務(wù)在等待cpu進行執(zhí)行,因此導致了有了不同的狀態(tài)
      Python多進程知識點總結(jié)

      • 就緒態(tài):運行的條件都已經(jīng)慢去,正在等在cpu執(zhí)行
      • 執(zhí)行態(tài):cpu正在執(zhí)行其功能
      • 等待態(tài):等待某些條件滿足,例如一個程序sleep了,此時就處于等待態(tài)

      二、進程的創(chuàng)建-multiprocessing

      1. Process類語法說明

      multiprocessing 模塊通過創(chuàng)建一個 Process 對象然后調(diào)用它的 start()方法來生成進程,Processthreading.Thread API 相同。

      語法格式multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

      參數(shù)說明

      • group:指定進程組,大多數(shù)情況下用不到
      • target:如果傳遞了函數(shù)的引用,可以任務(wù)這個子進程就執(zhí)行這里的代碼
      • name:給進程設(shè)定一個名字,可以不設(shè)定
      • args:給target指定的函數(shù)傳遞的參數(shù),以元組的方式傳遞
      • kwargs:給target指定的函數(shù)傳遞命名參數(shù)

      multiprocessing.Process 對象具有如下方法和屬性:

      方法名/屬性 說明
      run() 進程具體執(zhí)行的方法
      start() 啟動子進程實例(創(chuàng)建子進程)
      join([timeout]) 如果可選參數(shù) timeout 是默認值 None,則將阻塞至調(diào)用 join() 方法的進程終止;如果 timeout 是一個正數(shù),則最多會阻塞 timeout 秒
      name 當前進程的別名,默認為Process-N,N為從1開始遞增的整數(shù)
      pid 當前進程的pid(進程號)
      is_alive() 判斷進程子進程是否還在活著
      exitcode 子進程的退出代碼
      daemon 進程的守護標志,是一個布爾值。
      authkey 進程的身份驗證密鑰。
      sentinel 系統(tǒng)對象的數(shù)字句柄,當進程結(jié)束時將變?yōu)?ready。
      terminate() 不管任務(wù)是否完成,立即終止子進程
      kill() 與 terminate() 相同,但在 Unix 上使用 SIGKILL 信號。
      close() 關(guān)閉 Process 對象,釋放與之關(guān)聯(lián)的所有資源

      2. 2個while循環(huán)一起執(zhí)行

      # -*- coding:utf-8 -*-from multiprocessing import Processimport timedef run_proc():     """子進程要執(zhí)行的代碼"""     while True:         print("----2----")         time.sleep(1)if __name__=='__main__':     p = Process(target=run_proc)     p.start()     while True:         print("----1----")         time.sleep(1)

      運行結(jié)果:
      Python多進程知識點總結(jié)
      說明:創(chuàng)建子進程時,只需要傳入一個執(zhí)行函數(shù)和函數(shù)的參數(shù),創(chuàng)建一個Process實例,用start()方法啟動

      3. 進程pid

      # -*- coding:utf-8 -*-from multiprocessing import Processimport osimport timedef run_proc():     """子進程要執(zhí)行的代碼"""     print('子進程運行中,pid=%d...' % os.getpid())  # os.getpid獲取當前進程的進程號     print('子進程將要結(jié)束...')if __name__ == '__main__':     print('父進程pid: %d' % os.getpid())  # os.getpid獲取當前進程的進程號     p = Process(target=run_proc)     p.start()

      運行結(jié)果:
      Python多進程知識點總結(jié)

      4. 給子進程指定的函數(shù)傳遞參數(shù)

      # -*- coding:utf-8 -*-from multiprocessing import Processimport osfrom time import sleepdef run_proc(name, age, **kwargs):     for i in range(10):         print('子進程運行中,name= %s,age=%d ,pid=%d...' % (name, age, os.getpid()))         print(kwargs)         sleep(0.2)if __name__=='__main__':     p = Process(target=run_proc, args=('test',18), kwargs={"m":20})     p.start()     sleep(1)  # 1秒中之后,立即結(jié)束子進程     p.terminate()     p.join()

      運行結(jié)果:
      Python多進程知識點總結(jié)

      5. 進程間不同享全局變量

      # -*- coding:utf-8 -*-from multiprocessing import Processimport osimport time  nums = [11, 22]def work1():     """子進程要執(zhí)行的代碼"""     print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))     for i in range(3):         nums.append(i)         time.sleep(1)         print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums))def work2():     """子進程要執(zhí)行的代碼"""     print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums))if __name__ == '__main__':     p1 = Process(target=work1)     p1.start()     p1.join()      p2 = Process(target=work2)     p2.start()

      運行結(jié)果:

      in process1 pid=11349 ,nums=[11, 22]in process1 pid=11349 ,nums=[11, 22, 0]in process1 pid=11349 , nums=[11, 22, 0, 1]in process1 pid=11349 ,nums=[11, 22, 0, 1, 2]in process2 pid=11350 ,nums=[11, 22]

      三、進程間同步-Queue

      Process之間有時需要通信,操作系統(tǒng)提供了很多機制來實現(xiàn)進程間的通信。

      1. Queue類語法說明

      方法名 說明
      q=Queue() 初始化Queue()對象,若括號中沒有指定最大可接收的消息數(shù)量,或數(shù)量為負值,那么就代表可接受的消息數(shù)量沒有上限(直到內(nèi)存的盡頭)
      Queue.qsize() 返回當前隊列包含的消息數(shù)量
      Queue.empty() 如果隊列為空,返回True,反之False
      Queue.full() 如果隊列滿了,返回True,反之False
      Queue.get([block[, timeout]]) 獲取隊列中的一條消息,然后將其從列隊中移除,block默認值為True。1、如果block使用默認值,且沒有設(shè)置timeout(單位秒),消息列隊如果為空,此時程序?qū)⒈蛔枞ㄍT谧x取狀態(tài)),直到從消息列隊讀到消息為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒讀取到任何消息,則拋出"Queue.Empty"異常。2、如果block值為False,消息列隊如果為空,則會立刻拋出"Queue.Empty"異常
      Queue.get_nowait() 相當Queue.get(False)
      Queue.put(item,[block[, timeout]]) 將item消息寫入隊列,block默認值為True。1、如果block使用默認值,且沒有設(shè)置timeout(單位秒),消息列隊如果已經(jīng)沒有空間可寫入,此時程序?qū)⒈蛔枞ㄍT趯懭霠顟B(tài)),直到從消息列隊騰出空間為止,如果設(shè)置了timeout,則會等待timeout秒,若還沒空間,則拋出"Queue.Full"異常。 2、如果block值為False,消息列隊如果沒有空間可寫入,則會立刻拋出"Queue.Full"異常
      Queue.put_nowait(item) 相當Queue.put(item, False)

      2. Queue的使用

      可以使用multiprocessing模塊的Queue實現(xiàn)多進程之間的數(shù)據(jù)傳遞,Queue本身是一個消息列隊程序,首先用一個小實例來演示一下Queue的工作原理:

      #coding=utf-8from multiprocessing import Queue q=Queue(3) #初始化一個Queue對象,最多可接收三條put消息q.put("消息1") q.put("消息2")print(q.full())  #Falseq.put("消息3")print(q.full()) #True#因為消息列隊已滿下面的try都會拋出異常,第一個try會等待2秒后再拋出異常,第二個Try會立刻拋出異常try:     q.put("消息4",True,2)except:     print("消息列隊已滿,現(xiàn)有消息數(shù)量:%s"%q.qsize())try:     q.put_nowait("消息4")except:     print("消息列隊已滿,現(xiàn)有消息數(shù)量:%s"%q.qsize())#推薦的方式,先判斷消息列隊是否已滿,再寫入if not q.full():     q.put_nowait("消息4")#讀取消息時,先判斷消息列隊是否為空,再讀取if not q.empty():     for i in range(q.qsize()):         print(q.get_nowait())

      運行結(jié)果:

      FalseTrue消息列隊已滿,現(xiàn)有消息數(shù)量:3消息列隊已滿,現(xiàn)有消息數(shù)量:3消息1消息2消息3

      3. Queue實例

      我們以Queue為例,在父進程中創(chuàng)建兩個子進程,一個往Queue里寫數(shù)據(jù),一個從Queue里讀數(shù)據(jù):

      from multiprocessing import Process, Queueimport os, time, random# 寫數(shù)據(jù)進程執(zhí)行的代碼:def write(q):     for value in ['A', 'B', 'C']:         print('Put %s to queue...' % value)         q.put(value)         time.sleep(random.random())# 讀數(shù)據(jù)進程執(zhí)行的代碼:def read(q):     while True:         if not q.empty():             value = q.get(True)             print('Get %s from queue.' % value)             time.sleep(random.random())         else:             breakif __name__=='__main__':     # 父進程創(chuàng)建Queue,并傳給各個子進程:     q = Queue()     pw = Process(target=write, args=(q,))     pr = Process(target=read, args=(q,))     # 啟動子進程pw,寫入:     pw.start()         # 等待pw結(jié)束:     pw.join()     # 啟動子進程pr,讀取:     pr.start()     pr.join()     # pr進程里是死循環(huán),無法等待其結(jié)束,只能強行終止:     print('')     print('所有數(shù)據(jù)都寫入并且讀完')

      運行結(jié)果:
      Python多進程知識點總結(jié)

      四、進程間同步-Lock

      鎖是為了確保數(shù)據(jù)一致性。比如讀寫鎖,每個進程給一個變量增加 1,但是如果在一個進程讀取但還沒有寫入的時候,另外的進程也同時讀取了,并寫入該值,則最后寫入的值是錯誤的,這時候就需要加鎖來保持數(shù)據(jù)一致性。

      通過使用Lock來控制一段代碼在同一時間只能被一個進程執(zhí)行。Lock對象的兩個方法,acquire()用來獲取鎖,release()用來釋放鎖。當一個進程調(diào)用acquire()時,如果鎖的狀態(tài)為unlocked,那么會立即修改為locked并返回,這時該進程即獲得了鎖。如果鎖的狀態(tài)為locked,那么調(diào)用acquire()的進程則阻塞。

      1. Lock的語法說明

      • lock = multiprocessing.Lock(): 創(chuàng)建一個鎖

      • lock.acquire() :獲取鎖

      • lock.release() :釋放鎖

      • with lock:自動獲取、釋放鎖 類似于 with open() as f:

      2. 程序不加鎖時

      import multiprocessingimport timedef add(num, value):     print('add{0}:num={1}'.format(value, num))     for i in range(0, 2):         num += value        print('add{0}:num={1}'.format(value, num))         time.sleep(1)if __name__ == '__main__':     lock = multiprocessing.Lock()     num = 0     p1 = multiprocessing.Process(target=add, args=(num, 1))     p2 = multiprocessing.Process(target=add, args=(num, 2))     p1.start()     p2.start()

      運行結(jié)果:運得沒有順序,兩個進程交替運行

      add1:num=0add1:num=1add2:num=0add2:num=2add1:num=2add2:num=4

      3. 程序加鎖時

      import multiprocessingimport timedef add(num, value, lock):     try:         lock.acquire()         print('add{0}:num={1}'.format(value, num))         for i in range(0, 2):             num += value            print('add{0}:num={1}'.format(value, num))             time.sleep(1)     except Exception as err:         raise err    finally:         lock.release()if __name__ == '__main__':     lock = multiprocessing.Lock()     num = 0     p1 = multiprocessing.Process(target=add, args=(num, 1, lock))     p2 = multiprocessing.Process(target=add, args=(num, 2, lock))     p1.start()     p2.start()

      運行結(jié)果:只有當其中一個進程執(zhí)行完成后,其它的進程才會去執(zhí)行,且誰先搶到鎖誰先執(zhí)行

      add1:num=0add1:num=1add1:num=2add2:num=0add2:num=2add2:num=4

      五、進程池Pool

      當需要創(chuàng)建的子進程數(shù)量不多時,可以直接利用multiprocessing中的Process動態(tài)成生多個進程,但如果是上百甚至上千個目標,手動的去創(chuàng)建進程的工作量巨大,此時就可以用到multiprocessing模塊提供的Pool方法。

      1. Pool類語法說明

      語法格式multiprocessing.pool.Pool([processes[, initializer[, initargs[, maxtasksperchild[, context]]]]])

      參數(shù)說明

      • processes:工作進程數(shù)目,如果 processes 為 None,則使用 os.cpu_count() 返回的值。

      • initializer:如果 initializer 不為 None,則每個工作進程將會在啟動時調(diào)用 initializer(*initargs)。

      • maxtasksperchild:一個工作進程在它退出或被一個新的工作進程代替之前能完成的任務(wù)數(shù)量,為了釋放未使用的資源。

      • context:用于指定啟動的工作進程的上下文。

      兩種方式向進程池提交任務(wù)

      • apply(func[, args[, kwds]]):阻塞方式。

      • apply_async(func[, args[, kwds]]):非阻塞方式。使用非阻塞方式調(diào)用func(并行執(zhí)行,堵塞方式必須等待上一個進程退出才能執(zhí)行下一個進程),args為傳遞給func的參數(shù)列表,kwds為傳遞給func的關(guān)鍵字參數(shù)列表

      multiprocessing.Pool常用函數(shù):

      方法名 說明
      close() 關(guān)閉Pool,使其不再接受新的任務(wù)
      terminate() 不管任務(wù)是否完成,立即終止
      join() 主進程阻塞,等待子進程的退出, 必須在close或terminate之后使用

      2. Pool實例

      初始化Pool時,可以指定一個最大進程數(shù),當有新的請求提交到Pool中時,如果池還沒有滿,那么就會創(chuàng)建一個新的進程用來執(zhí)行該請求;但如果池中的進程數(shù)已經(jīng)達到指定的最大值,那么該請求就會等待,直到池中有進程結(jié)束,才會用之前的進程來執(zhí)行新的任務(wù),請看下面的實例:

      # -*- coding:utf-8 -*-from multiprocessing import Poolimport os, time, randomdef worker(msg):     t_start = time.time()     print("%s開始執(zhí)行,進程號為%d" % (msg,os.getpid()))     # random.random()隨機生成0~1之間的浮點數(shù)     time.sleep(random.random()*2)      t_stop = time.time()     print(msg,"執(zhí)行完畢,耗時%0.2f" % (t_stop-t_start))po = Pool(3)  # 定義一個進程池,最大進程數(shù)3for i in range(0,10):     # Pool().apply_async(要調(diào)用的目標,(傳遞給目標的參數(shù)元祖,))     # 每次循環(huán)將會用空閑出來的子進程去調(diào)用目標     po.apply_async(worker,(i,))print("----start----")po.close()       # 關(guān)閉進程池,關(guān)閉后po不再接收新的請求po.join()       # 等待po中所有子進程執(zhí)行完成,必須放在close語句之后print("-----end-----")

      運行結(jié)果:

      ----start---- 0開始執(zhí)行,進程號為21466 1開始執(zhí)行,進程號為21468 2開始執(zhí)行,進程號為21467 0 執(zhí)行完畢,耗時1.01 3開始執(zhí)行,進程號為21466 2 執(zhí)行完畢,耗時1.24 4開始執(zhí)行,進程號為21467 3 執(zhí)行完畢,耗時0.56 5開始執(zhí)行,進程號為21466 1 執(zhí)行完畢,耗時1.68 6開始執(zhí)行,進程號為21468 4 執(zhí)行完畢,耗時0.67 7開始執(zhí)行,進程號為21467 5 執(zhí)行完畢,耗時0.83 8開始執(zhí)行,進程號為21466 6 執(zhí)行完畢,耗時0.75 9開始執(zhí)行,進程號為21468 7 執(zhí)行完畢,耗時1.03 8 執(zhí)行完畢,耗時1.05 9 執(zhí)行完畢,耗時1.69 -----end-----

      3. 進程池中的Queue

      如果要使用Pool創(chuàng)建進程,就需要使用multiprocessing.Manager()中的Queue()

      而不是multiprocessing.Queue(),否則會得到一條如下的錯誤信息:RuntimeError: Queue objects should only be shared between processes through inheritance.

      下面的實例演示了進程池中的進程如何通信:

      # -*- coding:utf-8 -*-# 修改import中的Queue為Managerfrom multiprocessing import Manager,Poolimport os,time,randomdef reader(q):     print("reader啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))     for i in range(q.qsize()):         print("reader從Queue獲取到消息:%s" % q.get(True))def writer(q):     print("writer啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))     for i in "itcast":         q.put(i)if __name__=="__main__":     print("(%s) start" % os.getpid())     q = Manager().Queue()  # 使用Manager中的Queue     po = Pool()     po.apply_async(writer, (q,))      time.sleep(1)  # 先讓上面的任務(wù)向Queue存入數(shù)據(jù),然后再讓下面的任務(wù)開始從中取數(shù)據(jù)      po.apply_async(reader, (q,))     po.close()     po.join()     print("(%s) End" % os.getpid())

      運行結(jié)果:

      (11095) start writer啟動(11097),父進程為(11095)reader啟動(11098),父進程為(11095)reader從Queue獲取到消息:i reader從Queue獲取到消息:t reader從Queue獲取到消息:c reader從Queue獲取到消息:a reader從Queue獲取到消息:s reader從Queue獲取到消息:t(11095) End

      六、進程、線程對比

      1. 功能

      進程:能夠完成多任務(wù),比如 在一臺電腦上能夠同時運行多個QQ
      線程:能夠完成多任務(wù),比如 一個QQ中的多個聊天窗口

      定義的不同

      • 進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位.

      • 線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.

      2. 區(qū)別

      • 一個程序至少有一個進程,一個進程至少有一個線程.
        -線程的劃分尺度小于進程(資源比進程少),使得多線程程序的并發(fā)性高。
        -進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而極大地提高了程序的運行效率
        Python多進程知識點總結(jié)
      • 線線程不能夠獨立執(zhí)行,必須依存在進程中
      • 可以將進程理解為工廠中的一條流水線,而其中的線程就是這個流水線上的工人

      3. 優(yōu)缺點

      • 線程:線程執(zhí)行開銷小,但不利于資源的管理和保護
      • 進程:進程執(zhí)行開銷大,但利于資源的管理和保護

      推薦學習:python視頻教程

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號