中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Python中使用Process實現多進程

發布時間:2021-06-02 17:43:51 來源:億速云 閱讀:208 作者:Leah 欄目:開發技術

這期內容當中小編將會給大家帶來有關怎么在Python中使用Process實現多進程,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

進程的概念

程序是沒有運行的代碼,靜態的;

進程是運行起來的程序,進程是一個程序運行起來之后和資源的總稱;

程序只有一個,但同一份程序可以有多個進程;例如,電腦上多開QQ;

程序和進程的區別在于有沒有資源,進程有資源而程序沒有資源,進程是一個資源分配的基本單元;
程序在沒運行的時候沒有資源,沒有顯卡,沒有網卡,等等;雙擊運行后有攝像頭,有網速等等,就叫做進程;

進程的狀態

進程狀態圖

怎么在Python中使用Process實現多進程

  • 就緒態:運行的條件都已經慢去,正在等在cpu執行

  • 執行態:cpu正在執行其功能

  • 等待態:等待某些條件滿足,例如一個程序sleep了,此時就處于等待態

使用Process完成多任務

進程的使用步驟和線程的使用步驟基本一致;

進程的使用步驟:

  • 導入multiprocessing;

  • 編寫多任務所所需要的函數;

  • 創建multiprocessing.Process類的實例對象并傳入函數引用;

  • 調用實例對象的start方法,創建子線程。

進程使用步驟圖示:

怎么在Python中使用Process實現多進程

進程使用步驟代碼

import time
import multiprocessing
def sing():
  while True:
    print("-----sing-----")
    time.sleep(1)
def dance():
  while True:
    print("-----dance-----")
    time.sleep(1)
def main():
  p1 = multiprocessing.Process(target=sing)
  p2 = multiprocessing.Process(target=dance)
  p1.start()
  p2.start()
if __name__ == "__main__":
  main()

運行結果:

-----sing-----
-----dance-----
-----sing-----
-----dance-----
-----sing-----
-----dance-----
......

進程:

  • 主進程有什么,子進程就會有什么資源;

  • 線程能創建多任務,進程也能創建多任務,但進程耗費的資源比較大;

  • 所以運行的進程數,不一定越多越好;

  • 當創建子進程時,會復制一份主進程的資源,代碼,內存等,但又會有自己不同的地方,比如pid等;

  • 我們可以理解為多進程之間共享代碼,即只有一份代碼,但有多個指向同一代碼的箭頭;

  • 能共享的就共享,不能共享的就拷貝一份;不需要修改的就共享,要修改的時候就給你拷貝一份,這就是寫時拷貝;

獲取進程id

獲取進程id代碼

from multiprocessing import Process
import osdef run_proc():
  """子進程要執行的代碼"""
  print('子進程運行中,pid=%d...' % os.getpid()) # os.getpid獲取當前進程的進程號
  print('子進程將要結束...')

if __name__ == '__main__':
  print('父進程pid: %d' % os.getpid()) # os.getpid獲取當前進程的進程號
  p = Process(target=run_proc)
  p.start()

進程和線程對比

進程和線程的區別

  • 進程是系統進行資源分配和調度的一個獨立單位;

  • 線程是進程的一個實體,是CPU調度和分派的基本單位,即是操作系統調度的單位,它是比進程更小的能獨立運行的基本單位;

  • 一個程序至少有一個進程,一個進程至少有一個線程;

  • 線程的劃分尺度小于進程(資源比進程少),使得多線程程序的并發性高;

  • 進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率;

  • 線程不能夠獨立執行,必須依存在進程中;

  • 進程先有,才有的線程;

  • 線程用資源去做事;

  • 多線程能實現多任務是指在一個進程資源里面有多個箭頭;多線程是在同一個資源里面有多個箭頭執行同一份代碼;

  • 多進程的多任務是又開啟了一份資源,在這個資源里面又有一個箭頭;

  • 進程執行方式1:在一份資源里面有多個箭頭在執行;

  • 進程執行方式2:有多份資源,在每一份資源里面有一個箭頭執行代碼;

  • 線程執行開銷小,但不利于資源的管理和保護,進程正好相反;

  • 開發中還是多線程用的多;

通過隊列完成進程間通信

隊列使用語法

# 創建隊列:
from multiprocessing import Queue
q = Queue(3)
# 往隊列中添加數據:
q.put(xxx)
# 從隊列中獲取數據:
q.get()

通過隊列完成進程間通信代碼

from multiprocessing import Queue
import multiprocessing
def download_data(q):
  """模擬這是從網上下載數據"""
  data = [11, 22, 33]
  for i in data:
    q.put(i)
  print("數據下載完成")
def deal_data(q):
  """模擬處理從網上下載下來的數據"""
  data_list = []
  while True:
    data = q.get()
    data_list.append(data)
    if q.empty():
      break
  print("處理數據結束,數據為:", data_list)
def main():
  q = Queue(3)
  p1 = multiprocessing.Process(target=download_data, args=(q,))
  p2 = multiprocessing.Process(target=deal_data, args=(q,))
  p1.start()
  time.sleep(1)
  p2.start()
if __name__ == '__main__':
  main()

運行結果:

數據下載完成

處理數據結束,數據為: [11, 22, 33]

進程池完成多任務

進程池

進程池的概念

因為進程的創建和銷毀是需要大量的資源的,為了減少消耗,當我們在處理多任務時,比如100個任務,我們可以先創建10個進程,然后用這10個進程來執行者100個任務,就可以重復使用進程,達到節約資源的目的了,而這個就可以使用進程池。

進程池的創建

任務數固定且較少,用普通的進程即可;任務數不確定,且比較多,就用進程池;

進程池不會等待進程執行完畢,我們需要使用po.join()讓主進程等待進程池中的進程執行完;且po.close()必須在join前面;小編整理一套Python資料和PDF,有需要Python學習資料可以加學習群:631441315 ,反正閑著也是閑著呢,不如學點東西啦~~

創建進程池語法

# 創建進程池
from multiprocessing import Pool
po = Pool(3)

# 給進程池傳遞任務和參數
po.asyn(sing, (num,))

# 讓進程池等待子進程執行完
po.close()
po.join()

進程池pool示例

from multiprocessing import Pool
import os, time, random
def worker(msg):
  t_start = time.time()
  print("%s開始執行,進程號為%d" % (msg, os.getpid()))
  # random.random()隨機生成0~1之間的浮點數
  time.sleep(random.random() * 2)
  t_stop = time.time()
  print(msg, "執行完畢,耗時%0.2f" % (t_stop - t_start))
def main():
  po = Pool(3) # 定義一個進程池,最大進程數3
  for i in range(0, 10):
    # Pool().apply_async(要調用的目標,(傳遞給目標的參數元祖,))
    # 每次循環將會用空閑出來的子進程去調用目標
    po.apply_async(worker, (i,))

  print("----start----")
  po.close() # 關閉進程池,關閉后po不再接收新的請求
  po.join() # 等待po中所有子進程執行完成,必須放在close語句之后
  print("-----end-----")
if __name__ == '__main__':
  main()

執行結果:

----start----
0開始執行,進程號為7812
1開始執行,進程號為9984
2開始執行,進程號為1692
執行完畢,耗時0.65
3開始執行,進程號為9984
執行完畢,耗時1.08
4開始執行,進程號為7812
執行完畢,耗時1.82
5開始執行,進程號為1692
執行完畢,耗時1.12
6開始執行,進程號為7812
執行完畢,耗時1.35
7開始執行,進程號為9984
執行完畢,耗時0.11
8開始執行,進程號為9984
執行完畢,耗時0.50
9開始執行,進程號為7812
執行完畢,耗時0.65
執行完畢,耗時0.70
執行完畢,耗時0.74
-----end-----

多進程拷貝文件夾

多任務文件夾copy

步驟思路:

1.獲取用戶要拷貝的文件夾的名字;

2.創建一個新的文件夾;

3.獲取文件夾的所有待拷貝的文件名;listdir()

4.創建進程池;

5.復制原文件夾中的文件,到新文件夾的文件中去;

多任務拷貝文件代碼

import os
from multiprocessing import Pool
def copy_file(file, old_folder, new_folder):

  old_f = open(old_folder+"/"+file, "rb")
  data = old_f.read()
  old_f.close()

  new_f = open(new_folder+"/"+file, "wb")
  new_f.write(data)
  new_f.close()
  print("創建文件成功:", file)
def main():
  # 1.獲取要拷貝的文件夾
  old_folder = input("請輸入你要拷貝的文件夾:")
  # 2.創建新文件夾
  new_folder = old_folder + "_復件"
  try:
    os.mkdir(new_folder)
    print("創建文件夾成功")
  except Exception as e:
    pass
  # 3.獲取文件夾中所有待拷貝的文件,listdir()
  files_list = os.listdir(old_folder)
  # print(files_list)
  # 4.創建進程池
  po = Pool(5)
  for file in files_list:
    # 向進程池中添加復制文件的任務
    po.apply_async(copy_file, args=(file, old_folder, new_folder))
  # 復制原文件夾中的文件,到新文件夾中
  po.close()
  po.join()
if __name__ == '__main__':
  main()

在完成文件夾拷貝后,增加了一個需求,顯示拷貝文件的進度條,怎么辦?

多任務拷貝文件并顯示進度條

如果要在進程池中使用Queue,要使用from multiprocessing import Manager ,使用Manager().Queue();

顯示進度條思路:

  • 創建一個隊列;

  • 往拷貝文件的函數中傳入隊列,拷貝好一個文件就往q中傳入該文件名;

  • 在主函數中計算listdir()中的所有文件數量;

  • 在主函數中定義一個num,初始值為0;

  • 在主函數中定義一個while true,從q中獲取文件每獲取一個文件們就將num+1

  • 計算,如果num的值大于等于總文件數量,就break;

  • 使用已拷貝文件數量num除以總文件數量,即為拷貝的進度,使用開頭\r 和end=""讓顯示進度不換行,如下:

print("\r已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len), end="")

多任務拷貝文件并顯示進度條代碼:

import os
from multiprocessing import Pool, Manager
def copy_file(q, file, old_folder, new_folder):
  old_f = open(old_folder+"/"+file, "rb")
  data = old_f.read()
  old_f.close()
  new_f = open(new_folder+"/"+file, "wb")
  new_f.write(data)
  new_f.close()
  q.put(file)
def main():
  # 1.獲取要拷貝的文件夾
  old_folder = input("請輸入你要拷貝的文件夾:")
  # 2.創建新文件夾
  new_folder = old_folder + "_復件"
  try:
    os.mkdir(new_folder)
    print("創建文件夾成功")
  except Exception as e:
    pass
  # 3.獲取文件夾中所有待拷貝的文件,listdir()
  files_list = os.listdir(old_folder)
  # 4.創建進程池
  po = Pool(5)
  # 5.創建隊列
  q = Manager().Queue()
  # 6.復制原文件夾中的文件,到新文件夾中
  for file in files_list:
    # 向進程池中添加復制文件的任務
    po.apply_async(copy_file, args=(q, file, old_folder, new_folder))
  all_file_len = len(files_list)
  po.close()
  # po.join()
  copy_ok_file_num = 0
  while True:
    file = q.get()
    copy_ok_file_num += 1
    print("已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len))
    # print("\r已拷貝文件%.2f %%" % (copy_ok_file_num*100/all_file_len), end="")
    if copy_ok_file_num >= all_file_len:
      break
  print()
if __name__ == '__main__':
  main()

上述就是小編為大家分享的怎么在Python中使用Process實現多進程了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

井冈山市| 资讯| 大冶市| 广东省| 岳普湖县| 乐东| 罗甸县| 酒泉市| 岑巩县| 隆回县| 恩平市| 平潭县| 集安市| 九寨沟县| 于都县| 冀州市| 炎陵县| 富阳市| 壤塘县| 保定市| 武夷山市| 汉中市| 旌德县| 渭源县| 吕梁市| 广宁县| 边坝县| 安泽县| 汨罗市| 开封市| 龙口市| 监利县| 阿拉善右旗| 大庆市| 牙克石市| 富锦市| 阿图什市| 罗定市| 伊春市| 敦煌市| 郸城县|