multiprocessing中進程池,線程池的使用


multiprocessing

多進程基本使用

  1. 示例代碼1
import time
import random
from multiprocessing import Process

def run(name):
    print(f'{name} is running')
    time.sleep(random.randint(1,3))
    print(f'{name} is end')

if __name__ =='__main__':
    p_list = []
    for i in range(3):
        # 傳參的兩種方式
        # p = Process(target=run,kwargs={'name':f'線程{i}'})
        p = Process(target=run,args=(f"線程{i}",))

        p_list.append(p)
        p.start()
    # for i in p_list:
        # p.join()  # join后主進程會等待子進程都結束再結束
    print('主進程結束')
    # strat():方法的功能 1.開啟進程 2.執行功能
  1. 示例代碼2
import os
import time
import random
from multiprocessing import Process


class Run(Process):
    def __init__(self,name):
        super().__init__() 
        self.name = name
    def run(self):  # 必須實現run方法
        print(os.getppid(),os.getpid())
        print(f'{self.name} is running')
        time.sleep(random.randint(1,3))
        print(f'{self.name} is end')

if __name__ =='__main__':
    p_list = []
    for i in range(5):
        p = Run(f'線程{i}')
        p_list.append(p)
        p.start()

    for i in p_list:
        p.join()
    print('主進程結束',os.getpid())

進程池(from multiprocessing import Pool)

  1. 進程池原理
  2. 示例代碼(串行)
import os
import time
from multiprocessing import Pool

def task(n):
    print('{} is running'.format(os.getpid()))
    time.sleep(2)
    print('{} is done'.format(os.getpid()))
    return n**2

if __name__ == '__main__':
    # print(os.cpu_count())  #查看cpu個數
    p = Pool(4) # 最大四個進程
    for i in range(1,7): # 開7個任務
        ret = p.apply(task,args=(i,))  #同步的,一個運行完才執行另一個
        print(f'本次任務結束:{ret}')
    p.close() # 禁止往進程池內在添加任務
    p.join() # 等待進程池
    print('主進程')
  1. 示例代碼(並行)
import os
import time
from multiprocessing import Pool

def task(n):
    print('{} is running'.format(os.getpid()))
    time.sleep(2)
    print('{} is done'.format(os.getpid()))
    return n**2

if __name__ == '__main__':
    # print(os.cpu_count())  #查看cpu個數
    ret_lis = []
    p = Pool(4) # 最大四個進程
    for i in range(1,7): # 開7個任務
        ret = p.apply_async(task,args=(i,))  # 異步的,一個運行完才執行另一個
        ret_lis.append(ret)
    p.close() # 禁止往進程池內在添加任務
    p.join() # 等待進程池
    # print('主進程')
    print(_.get() for _ in ret_lis)

更多參數請參考:https://www.cnblogs.com/damumu/p/7321732.html

線程池(from multiprocessing.dummy import Pool)

  1. 線程池的原理
    • 線程池首先會維護一個任務隊列
    • 生成工作使用的線程(可以是自定義個數,也可以是系統默認)
    • 線程分別從隊列中取出任務,並執行,一個任務執行完成需要告訴主線程完成一個任務
    • 再從任務隊列中取出任務,直到所有任務為空,退出線程
  2. 為什么需要使用線程池       
      - 創建/銷毀線程伴隨着系統開銷,過於頻繁的創建/銷毀線程,會很大程度上影響處理效率。
            記創建線程消耗時間T1,執行任務消耗時間T2,銷毀線程消耗時間T3,如果T1+T3>T2,那說明開啟一個線程來執行這個任務太不划算了!在線程池緩存線程可用已有的閑置線程來執行新任務,避免了創建/銷毀帶來的系統開銷。
      - 線程並發數量過多,搶占系統資源從而導致阻塞。
          線程能共享系統資源,如果同時執行的線程過多,就有可能導致系統資源不足而產生阻塞的情況。
      - 對線程進行一些簡單的管理。
          比如:延時執行、定時循環執行的策略等,運用線程池都能進行很好的實現。
  3. 示例代碼
import requests
from multiprocessing.dummy import Pool


def get_source(url):
	ret = requests.get(url)
	return ret.text

def main():	
	urls = [
		# ...,
		# ...,
		# ...,
	]

	pool = Pool(5)
	ret_list = pool.map(get_source, urls)

	pool.close()
	# 調用join之前,先調用close函數,否則會出錯。執行完close后不會有新的線程加入到pool,
    # join函數等待所有子線程結束
	pool.join()

	for ret in ret_list:
		print(ret)
		print('*'*100)

	# 更多關於dummy的介紹:https://my.oschina.net/zyzzy/blog/115096

if __name__ == '__main__':
	main()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM