日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

PYTHON 之 多线程 and 多进程

發布時間:2023/12/20 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PYTHON 之 多线程 and 多进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

環境

  • xubuntu 16.04
  • anaconda
  • pycharm
  • python3.6
  • https://www.cnblogs.com/jokerbj/p/7460260.html
  • http://www.dabeaz.com/python/UnderstandingGIL.pdf

多線程 vs 多進程

  • 程序:一堆代碼以文本形式存入一個文檔

  • 進程: 程序運行的一個狀態

    • 包含地址空間,內存,數據棧等
    • 每個進程由自己完全獨立的運行環境,多進程共享數據是一個問題
  • 線程

    • 一個進程的獨立運行片段,一個進程可以由多個線程
    • 輕量化的進程
    • 一個進程的多個現成間共享數據和上下文運行環境
    • 共享互斥問題
  • 全局解釋器鎖(GIL)

    • Python代碼的執行是由python虛擬機進行控制
    • 在主循環中稚嫩更有一個控制線程在執行
  • Python包

    • thread:有問題,不好用,python3改成了_thread

    • threading: 通行的包

    • 案例01: 順序執行,耗時比較長

''' 利用time函數,生成兩個函數 順序調用 計算總的運行時間''' import timedef loop1():# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())loop1()loop2()print("All done at:", time.ctime())if __name__ == '__main__':main()

結果,順序執行:

Starting at: Sun Aug 11 16:05:23 2019 Start loop 1 at : Sun Aug 11 16:05:23 2019 End loop 1 at: Sun Aug 11 16:05:27 2019 Start loop 2 at : Sun Aug 11 16:05:27 2019 End loop 2 at: Sun Aug 11 16:05:29 2019 All done at: Sun Aug 11 16:05:29 2019
  • 案例02: 改用多線程,縮短總時間,使用_thread
''' 利用time函數,生成兩個函數 順序調用 計算總的運行時間''' import time import _thread as threaddef loop1():# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 啟動多線程的意思是用多線程去執行某個函數# 啟動多線程函數為start_new_thead# 參數兩個,一個是需要運行的函數名,第二是函數的參數作為元祖使用,為空則使用空元祖# 注意:如果函數只有一個參數,需要參數后由一個逗號thread.start_new_thread(loop1, ())thread.start_new_thread(loop2, ())print("All done at:", time.ctime())if __name__ == '__main__':main()while True:time.sleep(1)

沒有 while True:
time.sleep(1)
運行結果(不等其他線程完成,主線程就完成了):
有 while True:
time.sleep(1)
運行結果(主線程死等):

  • 案例03: 多線程,傳參數
#利用time延時函數,生成兩個函數 # 利用多線程調用 # 計算總運行時間 # 練習帶參數的多線程啟動方法 import time # 導入多線程包并更名為thread import _thread as threaddef loop1(in1):# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 把參數打印出來print("我是參數 ",in1)# 睡眠多長時間,單位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 把參數in 和 in2打印出來,代表使用print("我是參數 " ,in1 , "和參數 ", in2)# 睡眠多長時間,單位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 啟動多線程的意思是用多線程去執行某個函數# 啟動多線程函數為start_new_thead# 參數兩個,一個是需要運行的函數名,第二是函數的參數作為元祖使用,為空則使用空元祖# 注意:如果函數只有一個參數,需要參數后由一個逗號thread.start_new_thread(loop1,("王老大", ))thread.start_new_thread(loop2,("王大鵬", "王曉鵬"))print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while語句# 因為啟動多線程后本程序就作為主線程存在# 如果主線程執行完畢,則子線程可能也需要終止while True:time.sleep(10)
  • threading的使用
    • 直接利用threading.Thread生成Thread實例
    • t = threading.Thread(target=xxx, args=(xxx,))
    • t.start():啟動多線程
    • t.join(): 等待多線程執行完成
    • 案例04
#利用time延時函數,生成兩個函數 # 利用多線程調用 # 計算總運行時間 # 練習帶參數的多線程啟動方法 import time # 導入多線程處理包 import threadingdef loop1(in1):# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 把參數打印出來print("我是參數 ",in1)# 睡眠多長時間,單位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 把參數in 和 in2打印出來,代表使用print("我是參數 " ,in1 , "和參數 ", in2)# 睡眠多長時間,單位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread實例t1 = threading.Thread(target=loop1, args=("王老大",))t1.start()t2 = threading.Thread(target=loop2, args=("王大鵬", "王小鵬"))t2.start()print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while語句# 因為啟動多線程后本程序就作為主線程存在# 如果主線程執行完畢,則子線程可能也需要終止while True:time.sleep(10)


5. 案例05: 加入join后比較跟案例04的結果的異同

#利用time延時函數,生成兩個函數 # 利用多線程調用 # 計算總運行時間 # 練習帶參數的多線程啟動方法 import time # 導入多線程處理包 import threadingdef loop1(in1):# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 把參數打印出來print("我是參數 ",in1)# 睡眠多長時間,單位是秒time.sleep(4)print('End loop 1 at:', time.ctime())def loop2(in1, in2):# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 把參數in 和 in2打印出來,代表使用print("我是參數 " ,in1 , "和參數 ", in2)# 睡眠多長時間,單位是秒time.sleep(2)print('End loop 2 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread實例t1 = threading.Thread(target=loop1, args=("王老大",))t1.start()t2 = threading.Thread(target=loop2, args=("王大鵬", "王小鵬"))t2.start()t1.join()t2.join()print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while語句# 因為啟動多線程后本程序就作為主線程存在# 如果主線程執行完畢,則子線程可能也需要終止while True:time.sleep(10)

運行結果:
Starting at: Sun Aug 11 16:19:40 2019
Start loop 1 at : Sun Aug 11 16:19:40 2019
我是參數 王老大
Start loop 2 at : Sun Aug 11 16:19:40 2019
我是參數 王大鵬 和參數 王小鵬
End loop 2 at: Sun Aug 11 16:19:42 2019
End loop 1 at: Sun Aug 11 16:19:44 2019
All done at: Sun Aug 11 16:19:44 2019

  • 守護線程-daemon
    - 如果在程序中將子線程設置成守護線程,則子線程會在主線程結束的時候自動退出
    - 一般認為,守護線程不重要或者不允許離開主線程獨立運行
    - 守護線程案例能否有效果跟環境相關
    - 案例06非守護線程
import time import threadingdef fun():print("Start fun")time.sleep(2)print("end fun")print("Main thread")t1 = threading.Thread(target=fun, args=() ) t1.start()time.sleep(1) print("Main thread end")

  • 案例07守護線程
import time import threadingdef fun():print("Start fun")time.sleep(2)print("end fun")print("Main thread")t1 = threading.Thread(target=fun, args=() ) # 社會守護線程的方法,必須在start之前設置,否則無效 t1.setDaemon(True) #t1.daemon = True t1.start()time.sleep(1) print("Main thread end")


主線程dead,子線程也dead

  • 線程常用屬性
    - threading.currentThread:返回當前線程變量
    - threading.enumerate:返回一個包含正在運行的線程的list,正在運行的線程指的是線程啟動后,結束前的狀態
    - threading.activeCount: 返回正在運行的線程數量,效果跟 len(threading.enumerate)相同
    - thr.setName: 給線程設置名字
    - thr.getName: 得到線程的名字
import time import threadingdef loop1():# ctime 得到當前時間print('Start loop 1 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(6)print('End loop 1 at:', time.ctime())def loop2():# ctime 得到當前時間print('Start loop 2 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(1)print('End loop 2 at:', time.ctime())def loop3():# ctime 得到當前時間print('Start loop 3 at :', time.ctime())# 睡眠多長時間,單位是秒time.sleep(5)print('End loop 3 at:', time.ctime())def main():print("Starting at:", time.ctime())# 生成threading.Thread實例t1 = threading.Thread(target=loop1, args=( ))# setName是給每一個子線程設置一個名字t1.setName("THR_1")t1.start()t2 = threading.Thread(target=loop2, args=( ))t2.setName("THR_2")t2.start()t3 = threading.Thread(target=loop3, args=( ))t3.setName("THR_3")t3.start()# 預期3秒后,thread2已經自動結束,time.sleep(3)# enumerate 得到正在運行子線程,即子線程1和子線程3for thr in threading.enumerate():# getName能夠得到線程的名字print("正在運行的線程名字是: {0}".format(thr.getName()))print("正在運行的子線程數量為: {0}".format(threading.activeCount()))print("All done at:", time.ctime())if __name__ == "__main__":main()# 一定要有while語句# 因為啟動多線程后本程序就作為主線程存在# 如果主線程執行完畢,則子線程可能也需要終止while True:time.sleep(10)

  • 直接繼承自threading.Thread

    - 直接繼承Thread
    - 重寫run函數
    - 類實例可以直接運行
    • 案例09
import threading import time# 1. 類需要繼承自threading.Thread class MyThread(threading.Thread):def __init__(self, arg):super(MyThread, self).__init__()self.arg = arg# 2 必須重寫run函數,run函數代表的是真正執行的功能def run(self):time.sleep(2)print("The args for this class is {0}".format(self.arg))for i in range(5):t = MyThread(i)t.start()t.join()print("Main thread is done!!!!!!!!")

  • 案例10, 工業風案例
import threading from time import sleep, ctimeloop = [4,2]class ThreadFunc:def __init__(self, name):self.name = namedef loop(self, nloop, nsec):''':param nloop: loop函數的名稱:param nsec: 系統休眠時間:return:'''print('Start loop ', nloop, 'at ', ctime())sleep(nsec)print('Done loop ', nloop, ' at ', ctime())def main():print("Starting at: ", ctime())# ThreadFunc("loop").loop 跟一下兩個式子相等:# t = ThreadFunc("loop")# t.loop# 以下t1 和 t2的定義方式相等t = ThreadFunc("loop")t1 = threading.Thread( target = t.loop, args=("LOOP1", 4))# 下面這種寫法更西方人,工業化一點t2 = threading.Thread( target = ThreadFunc('loop').loop, args=("LOOP2", 2))# 常見錯誤寫法#t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))#t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))t1.start()t2.start()t1.join( )t2.join()print("ALL done at: ", ctime())if __name__ == '__main__':main()

常用錯誤寫法:
t1 = threading.Thread(target=ThreadFunc(‘loop’).loop(100,4))
t2 = threading.Thread(target=ThreadFunc(‘loop’).loop(100,2))

import threading from time import sleep, ctimeloop = [4,2]class ThreadFunc:def __init__(self, name):self.name = namedef loop(self, nloop, nsec):''':param nloop: loop函數的名稱:param nsec: 系統休眠時間:return:'''print('Start loop ', nloop, 'at ', ctime())sleep(nsec)print('Done loop ', nloop, ' at ', ctime())def main():print("Starting at: ", ctime())# ThreadFunc("loop").loop 跟一下兩個式子相等:# t = ThreadFunc("loop")# t.loop# 以下t1 和 t2的定義方式相等t = ThreadFunc("loop")# 常見錯誤寫法t1 = threading.Thread(target=ThreadFunc('loop').loop(100,4))t2 = threading.Thread(target=ThreadFunc('loop').loop(100,2))t1.start()t2.start()t1.join( )t2.join()print("ALL done at: ", ctime())if __name__ == '__main__':main()

錯誤結果:兩個線程沒有同時運行

  • 共享變量
    • 共享變量: 當多個線程同時訪問一個變量的時候,會產生共享變量的問題
    • 案例11
import threadingsum = 0 loopSum = 1000000def myAdd():global sum, loopSumfor i in range(1, loopSum):sum += 1def myMinu():global sum, loopSumfor i in range(1, loopSum):sum -= 1if __name__ == '__main__':print("Starting ....{0}".format(sum))# 開始多線程的實例,看執行結果是否一樣t1 = threading.Thread(target=myAdd, args=())t2 = threading.Thread(target=myMinu, args=())t1.start()t2.start()t1.join()t2.join()print("Done .... {0}".format(sum))

  • 解決變量:鎖,信號燈,
  • 鎖(Lock)
    • 是一個標志,表示一個線程在占用一些資源
    • 使用方法:
      • 定義lock = threading.Lock()
      • 上鎖 lock.acquire()
      • 使用共享資源,放心的用
      • 取消鎖,釋放鎖 lock.release()
    • 案例12
import threadingsum = 0 loopSum = 1000000lock = threading.Lock()def myAdd():global sum, loopSumfor i in range(1, loopSum):# 上鎖,申請鎖lock.acquire()sum += 1# 釋放鎖lock.release()def myMinu():global sum, loopSumfor i in range(1, loopSum):lock.acquire()sum -= 1lock.release()if __name__ == '__main__':print("Starting ....{0}".format(sum))# 開始多線程的實例,看執行結果是否一樣t1 = threading.Thread(target=myAdd, args=())t2 = threading.Thread(target=myMinu, args=())t1.start()t2.start()t1.join()t2.join()print("Done .... {0}".format(sum))

  • 鎖誰: 哪個資源需要多個線程共享,鎖哪個
    - 理解鎖:鎖其實不是鎖住誰,而是一個令牌
    • 線程安全問題:
      • 如果一個資源/變量,他對于多線程來講,不用加鎖也不會引起任何問題,則稱為線程安全
      • 線程不安全變量類型: list, set, dict
      • 線程安全變量類型:queue 隊列
    • 生產者消費者問題
      • 一個模型,可以用來搭建消息隊列
      • queue是一個用來存放變量的數據結構,特點是先進先出,內部元素排隊,可以理解成一個特殊的list
      • 案例13
#encoding=utf-8 import threading import time# Python2 # from Queue import Queue# Python3 import queueclass Producer(threading.Thread):def run(self):global queuecount = 0while True:# qsize返回queue內容長度if queue.qsize() < 1000:for i in range(100):count = count +1msg = '生成產品'+str(count)# put是網queue中放入一個值queue.put(msg)print(msg)time.sleep(0.5)class Consumer(threading.Thread):def run(self):global queuewhile True:if queue.qsize() > 100:for i in range(3):# get是從queue中取出一個值msg = self.name + '消費了 '+queue.get()print(msg)time.sleep(1)if __name__ == '__main__':queue = queue.Queue()for i in range(500):queue.put('初始產品'+str(i))for i in range(2):p = Producer()p.start()for i in range(5):c = Consumer()c.start()

  • 死鎖問題, 案例14
import threading import timelock_1 = threading.Lock() lock_2 = threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire()print("func_1 申請了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")lock_2.acquire()print("func_1 申請了 lock_2.......")lock_2.release()print("func_1 釋放了 lock_2")lock_1.release()print("func_1 釋放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申請了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申請了 lock_1.......")lock_1.release()print("func_2 釋放了 lock_1")lock_2.release()print("func_2 釋放了 lock_2")print("func_2 done..........")if __name__ == "__main__":print("主程序啟動..............")t1 = threading.Thread(target=func_1, args=())t2 = threading.Thread(target=func_2, args=())t1.start()t2.start()t1.join()t2.join()print("主程序啟動..............")


func_1,func_2產生死鎖

  • 鎖的等待時間問題,案例15
  • lock_1.acquire(timeout=4)
  • rst = lock_2.acquire(timeout=2)
import threading import timelock_1 = threading.Lock() lock_2 = threading.Lock()def func_1():print("func_1 starting.........")lock_1.acquire(timeout=4)print("func_1 申請了 lock_1....")time.sleep(2)print("func_1 等待 lock_2.......")rst = lock_2.acquire(timeout=2)if rst:print("func_1 已經得到鎖 lock_2")lock_2.release()print("func_1 釋放了鎖 lock_2")else:print("func_1 注定沒申請到lock_2.....")lock_1.release()print("func_1 釋放了 lock_1")print("func_1 done..........")def func_2():print("func_2 starting.........")lock_2.acquire()print("func_2 申請了 lock_2....")time.sleep(4)print("func_2 等待 lock_1.......")lock_1.acquire()print("func_2 申請了 lock_1.......")lock_1.release()print("func_2 釋放了 lock_1")lock_2.release()print("func_2 釋放了 lock_2")print("func_2 done..........")if __name__ == "__main__":print("主程序啟動..............")t1 = threading.Thread(target=func_1, args=())t2 = threading.Thread(target=func_2, args=())t1.start()t2.start()t1.join()t2.join()print("主程序結束..............")

  • semphore 信號燈
    • 允許一個資源最多由幾個多線程同時使用
    • 案例16
import threading import time# 參數定義最多幾個線程同時使用資源 semaphore = threading.Semaphore(3)def func():if semaphore.acquire():for i in range(5):print(threading.currentThread().getName() + ' get semaphore')time.sleep(15)semaphore.release()print(threading.currentThread().getName() + ' release semaphore')for i in range(8):t1 = threading.Thread(target=func)t1.start()

  • threading.Timer
    • 案例 17
import threading import timedef func():print("I am running.........")time.sleep(4)print("I am done......")if __name__ == "__main__":t = threading.Timer(6, func)t.start()i = 0while True:print("{0}***************".format(i))time.sleep(3)i += 1

  • Timer是利用多線程,在指定時間后啟動一個功能

  • 可重入鎖

    • 一個鎖,可以被一個線程多次申請
    • 主要解決遞歸調用的時候,需要申請鎖的情況
    • 案例18
import threading import timeclass MyThread(threading.Thread):def run(self):global numtime.sleep(1)if mutex.acquire(1):num = num+1msg = self.name+' set num to '+str(num)print(msg)mutex.acquire()mutex.release()mutex.release()num = 0mutex = threading.RLock()def testTh():for i in range(5):t = MyThread()t.start()if __name__ == '__main__':testTh()

線程替代方案

  • subprocess

    • 完全跳過線程,使用進程
    • 是派生進程的主要替代方案
    • python2.4后引入
  • multiprocessiong

    • 使用threadiing借口派生,使用子進程
    • 允許為多核或者多cpu派生進程,接口跟threading非常相似
    • python2.6
  • concurrent.futures

    • 新的異步執行模塊
    • 任務級別的操作
    • python3.2后引入

多進程

  • 進程間通訊(InterprocessCommunication, IPC )
  • 進程之間無任何共享狀態
  • 進程的創建
    • 直接生成Process實例對象, 案例19
import multiprocessing from time import sleep, ctimedef clock(interval):while True:print("The time is %s" % ctime())sleep(interval)if __name__ == '__main__':p = multiprocessing.Process(target = clock, args = (5,))p.start()while True:print('sleeping.......')sleep(1)

  • 派生子類, 案例20
import multiprocessing from time import sleep, ctimeclass ClockProcess(multiprocessing.Process):'''兩個函數比較重要1. init構造函數2. run'''def __init__(self, interval):super().__init__()self.interval = intervaldef run(self):while True:print("The time is %s" % ctime())sleep(self.interval)if __name__ == '__main__':p = ClockProcess(3)p.start()while True:print('sleeping.......')sleep(1)

  • 在os中查看pid,ppid以及他們的關系
    • 案例21
from multiprocessing import Process import osdef info(title):print(title)print('module name:', __name__)# 得到父親進程的idprint('parent process:', os.getppid())# 得到本身進程的idprint('process id:', os.getpid())def f(name):info('function f')print('hello', name)if __name__ == '__main__':info('main line')p = Process(target=f, args=('bob',))p.start()p.join()

  • 生產者消費者模型
    • JoinableQueue
    • 案例22
import multiprocessing from time import ctimedef consumer(input_q):print("Into consumer:", ctime())while True:# 處理項item = input_q.get()print ("pull", item, "out of q") # 此處替換為有用的工作input_q.task_done() # 發出信號通知任務完成print ("Out of consumer:", ctime()) ##此句未執行,因為q.join()收集到四個task_done()信號后,主進程啟動,未等到print此句完成,程序就結束了def producer(sequence, output_q):print ("Into procuder:", ctime())for item in sequence:output_q.put(item)print ("put", item, "into q")print ("Out of procuder:", ctime())# 建立進程 if __name__ == '__main__':q = multiprocessing.JoinableQueue()# 運行消費者進程cons_p = multiprocessing.Process (target = consumer, args = (q,))cons_p.daemon = Truecons_p.start()# 生產多個項,sequence代表要發送給消費者的項序列# 在實踐中,這可能是生成器的輸出或通過一些其他方式生產出來sequence = [1,2,3,4]producer(sequence, q)# 等待所有項被處理q.join()

設置哨兵問題

  • 設置退出機制,使得消費者不陷入死循環
    • 采用的方式,是發送一個不可能出現的數據給joinablequeue!
  • 隊列中哨兵的使用, 案例23
import multiprocessing from time import ctime# 設置哨兵問題 def consumer(input_q):print("Into consumer:", ctime())while True:item = input_q.get()if item is None:breakprint("pull", item, "out of q")print ("Out of consumer:", ctime()) ## 此句執行完成,再轉入主進程def producer(sequence, output_q):print ("Into procuder:", ctime())for item in sequence:output_q.put(item)print ("put", item, "into q")print ("Out of procuder:", ctime())if __name__ == '__main__':q = multiprocessing.Queue()cons_p = multiprocessing.Process(target = consumer, args = (q,))cons_p.start()sequence = [1,2,3,4]producer(sequence, q)q.put(None)cons_p.join()
如果有多個消費者的情況,進行哨兵的改進!
  • 哨兵的改進, 案例24
  • 設置多個哨兵!
import multiprocessing from time import ctimedef consumer(input_q):print ("Into consumer:", ctime())while True:item = input_q.get()if item is None:breakprint("pull", item, "out of q")print ("Out of consumer:", ctime())def producer(sequence, output_q):for item in sequence:print ("Into procuder:", ctime())output_q.put(item)print ("Out of procuder:", ctime())if __name__ == '__main__':q = multiprocessing.Queue()cons_p1 = multiprocessing.Process (target = consumer, args = (q,))cons_p1.start()cons_p2 = multiprocessing.Process (target = consumer, args = (q,))cons_p2.start()sequence = [1,2,3,4]producer(sequence, q)q.put(None)q.put(None)cons_p1.join()cons_p2.join()

總結

以上是生活随笔為你收集整理的PYTHON 之 多线程 and 多进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。