最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python Process多進(jìn)程實(shí)現(xiàn)過程

 更新時(shí)間:2019年10月22日 09:05:50   作者:Python小老弟  
這篇文章主要介紹了Python Process多進(jìn)程實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

進(jìn)程的概念

程序是沒有運(yùn)行的代碼,靜態(tài)的;

進(jìn)程是運(yùn)行起來的程序,進(jìn)程是一個(gè)程序運(yùn)行起來之后和資源的總稱;

程序只有一個(gè),但同一份程序可以有多個(gè)進(jìn)程;例如,電腦上多開QQ;

程序和進(jìn)程的區(qū)別在于有沒有資源,進(jìn)程有資源而程序沒有資源,進(jìn)程是一個(gè)資源分配的基本單元;
程序在沒運(yùn)行的時(shí)候沒有資源,沒有顯卡,沒有網(wǎng)卡,等等;雙擊運(yùn)行后有攝像頭,有網(wǎng)速等等,就叫做進(jìn)程;

進(jìn)程的狀態(tài)

進(jìn)程狀態(tài)圖


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

使用Process完成多任務(wù)

進(jìn)程的使用步驟和線程的使用步驟基本一致;

進(jìn)程的使用步驟:

  • 導(dǎo)入multiprocessing;
  • 編寫多任務(wù)所所需要的函數(shù);
  • 創(chuàng)建multiprocessing.Process類的實(shí)例對象并傳入函數(shù)引用;
  • 調(diào)用實(shí)例對象的start方法,創(chuàng)建子線程。

進(jìn)程使用步驟圖示:

進(jìn)程使用步驟代碼

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()

運(yùn)行結(jié)果:

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

進(jìn)程:

  • 主進(jìn)程有什么,子進(jìn)程就會(huì)有什么資源;
  • 線程能創(chuàng)建多任務(wù),進(jìn)程也能創(chuàng)建多任務(wù),但進(jìn)程耗費(fèi)的資源比較大;
  • 所以運(yùn)行的進(jìn)程數(shù),不一定越多越好;
  • 當(dāng)創(chuàng)建子進(jìn)程時(shí),會(huì)復(fù)制一份主進(jìn)程的資源,代碼,內(nèi)存等,但又會(huì)有自己不同的地方,比如pid等;
  • 我們可以理解為多進(jìn)程之間共享代碼,即只有一份代碼,但有多個(gè)指向同一代碼的箭頭;
  • 能共享的就共享,不能共享的就拷貝一份;不需要修改的就共享,要修改的時(shí)候就給你拷貝一份,這就是寫時(shí)拷貝;

獲取進(jìn)程id

獲取進(jìn)程id代碼

from multiprocessing import Process
import osdef run_proc():
  """子進(jìn)程要執(zhí)行的代碼"""
  print('子進(jìn)程運(yùn)行中,pid=%d...' % os.getpid()) # os.getpid獲取當(dāng)前進(jìn)程的進(jìn)程號(hào)
  print('子進(jìn)程將要結(jié)束...')

if __name__ == '__main__':
  print('父進(jìn)程pid: %d' % os.getpid()) # os.getpid獲取當(dāng)前進(jìn)程的進(jìn)程號(hào)
  p = Process(target=run_proc)
  p.start()

進(jìn)程和線程對比

進(jìn)程和線程的區(qū)別

  • 進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位;
  • 線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,即是操作系統(tǒng)調(diào)度的單位,它是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位;
  • 一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程;
  • 線程的劃分尺度小于進(jìn)程(資源比進(jìn)程少),使得多線程程序的并發(fā)性高;
  • 進(jìn)程在執(zhí)行過程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率;
  • 線程不能夠獨(dú)立執(zhí)行,必須依存在進(jìn)程中;
  • 進(jìn)程先有,才有的線程;
  • 線程用資源去做事;
  • 多線程能實(shí)現(xiàn)多任務(wù)是指在一個(gè)進(jìn)程資源里面有多個(gè)箭頭;多線程是在同一個(gè)資源里面有多個(gè)箭頭執(zhí)行同一份代碼;
  • 多進(jìn)程的多任務(wù)是又開啟了一份資源,在這個(gè)資源里面又有一個(gè)箭頭;
  • 進(jìn)程執(zhí)行方式1:在一份資源里面有多個(gè)箭頭在執(zhí)行;
  • 進(jìn)程執(zhí)行方式2:有多份資源,在每一份資源里面有一個(gè)箭頭執(zhí)行代碼;
  • 線程執(zhí)行開銷小,但不利于資源的管理和保護(hù),進(jìn)程正好相反;
  • 開發(fā)中還是多線程用的多;

通過隊(duì)列完成進(jìn)程間通信

隊(duì)列使用語法

# 創(chuàng)建隊(duì)列:
from multiprocessing import Queue
q = Queue(3)
# 往隊(duì)列中添加數(shù)據(jù):
q.put(xxx)
# 從隊(duì)列中獲取數(shù)據(jù):
q.get()

通過隊(duì)列完成進(jìn)程間通信代碼

from multiprocessing import Queue
import multiprocessing
def download_data(q):
  """模擬這是從網(wǎng)上下載數(shù)據(jù)"""
  data = [11, 22, 33]
  for i in data:
    q.put(i)
  print("數(shù)據(jù)下載完成")
def deal_data(q):
  """模擬處理從網(wǎng)上下載下來的數(shù)據(jù)"""
  data_list = []
  while True:
    data = q.get()
    data_list.append(data)
    if q.empty():
      break
  print("處理數(shù)據(jù)結(jié)束,數(shù)據(jù)為:", 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()

運(yùn)行結(jié)果:

數(shù)據(jù)下載完成

處理數(shù)據(jù)結(jié)束,數(shù)據(jù)為: [11, 22, 33]

進(jìn)程池完成多任務(wù)

進(jìn)程池

進(jìn)程池的概念

因?yàn)檫M(jìn)程的創(chuàng)建和銷毀是需要大量的資源的,為了減少消耗,當(dāng)我們在處理多任務(wù)時(shí),比如100個(gè)任務(wù),我們可以先創(chuàng)建10個(gè)進(jìn)程,然后用這10個(gè)進(jìn)程來執(zhí)行者100個(gè)任務(wù),就可以重復(fù)使用進(jìn)程,達(dá)到節(jié)約資源的目的了,而這個(gè)就可以使用進(jìn)程池。

進(jìn)程池的創(chuàng)建

任務(wù)數(shù)固定且較少,用普通的進(jìn)程即可;任務(wù)數(shù)不確定,且比較多,就用進(jìn)程池;

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

創(chuàng)建進(jìn)程池語法

# 創(chuàng)建進(jìn)程池
from multiprocessing import Pool
po = Pool(3)

# 給進(jìn)程池傳遞任務(wù)和參數(shù)
po.asyn(sing, (num,))

# 讓進(jìn)程池等待子進(jìn)程執(zhí)行完
po.close()
po.join()

進(jìn)程池pool示例

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

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

執(zhí)行結(jié)果:

----start----
0開始執(zhí)行,進(jìn)程號(hào)為7812
1開始執(zhí)行,進(jìn)程號(hào)為9984
2開始執(zhí)行,進(jìn)程號(hào)為1692
執(zhí)行完畢,耗時(shí)0.65
3開始執(zhí)行,進(jìn)程號(hào)為9984
執(zhí)行完畢,耗時(shí)1.08
4開始執(zhí)行,進(jìn)程號(hào)為7812
執(zhí)行完畢,耗時(shí)1.82
5開始執(zhí)行,進(jìn)程號(hào)為1692
執(zhí)行完畢,耗時(shí)1.12
6開始執(zhí)行,進(jìn)程號(hào)為7812
執(zhí)行完畢,耗時(shí)1.35
7開始執(zhí)行,進(jìn)程號(hào)為9984
執(zhí)行完畢,耗時(shí)0.11
8開始執(zhí)行,進(jìn)程號(hào)為9984
執(zhí)行完畢,耗時(shí)0.50
9開始執(zhí)行,進(jìn)程號(hào)為7812
執(zhí)行完畢,耗時(shí)0.65
執(zhí)行完畢,耗時(shí)0.70
執(zhí)行完畢,耗時(shí)0.74
-----end-----

多進(jìn)程拷貝文件夾

多任務(wù)文件夾copy

步驟思路:

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

2.創(chuàng)建一個(gè)新的文件夾;

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

4.創(chuàng)建進(jìn)程池;

5.復(fù)制原文件夾中的文件,到新文件夾的文件中去;

多任務(wù)拷貝文件代碼

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("創(chuàng)建文件成功:", file)
def main():
  # 1.獲取要拷貝的文件夾
  old_folder = input("請輸入你要拷貝的文件夾:")
  # 2.創(chuàng)建新文件夾
  new_folder = old_folder + "_復(fù)件"
  try:
    os.mkdir(new_folder)
    print("創(chuàng)建文件夾成功")
  except Exception as e:
    pass
  # 3.獲取文件夾中所有待拷貝的文件,listdir()
  files_list = os.listdir(old_folder)
  # print(files_list)
  # 4.創(chuàng)建進(jìn)程池
  po = Pool(5)
  for file in files_list:
    # 向進(jìn)程池中添加復(fù)制文件的任務(wù)
    po.apply_async(copy_file, args=(file, old_folder, new_folder))
  # 復(fù)制原文件夾中的文件,到新文件夾中
  po.close()
  po.join()
if __name__ == '__main__':
  main()

在完成文件夾拷貝后,增加了一個(gè)需求,顯示拷貝文件的進(jìn)度條,怎么辦?

多任務(wù)拷貝文件并顯示進(jìn)度條

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

顯示進(jìn)度條思路:

  • 創(chuàng)建一個(gè)隊(duì)列;
  • 往拷貝文件的函數(shù)中傳入隊(duì)列,拷貝好一個(gè)文件就往q中傳入該文件名;
  • 在主函數(shù)中計(jì)算listdir()中的所有文件數(shù)量;
  • 在主函數(shù)中定義一個(gè)num,初始值為0;
  • 在主函數(shù)中定義一個(gè)while true,從q中獲取文件每獲取一個(gè)文件們就將num+1
  • 計(jì)算,如果num的值大于等于總文件數(shù)量,就break;
  • 使用已拷貝文件數(shù)量num除以總文件數(shù)量,即為拷貝的進(jìn)度,使用開頭\r 和end=""讓顯示進(jìn)度不換行,如下:

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

多任務(wù)拷貝文件并顯示進(jìn)度條代碼:

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.創(chuàng)建新文件夾
  new_folder = old_folder + "_復(fù)件"
  try:
    os.mkdir(new_folder)
    print("創(chuàng)建文件夾成功")
  except Exception as e:
    pass
  # 3.獲取文件夾中所有待拷貝的文件,listdir()
  files_list = os.listdir(old_folder)
  # 4.創(chuàng)建進(jìn)程池
  po = Pool(5)
  # 5.創(chuàng)建隊(duì)列
  q = Manager().Queue()
  # 6.復(fù)制原文件夾中的文件,到新文件夾中
  for file in files_list:
    # 向進(jìn)程池中添加復(fù)制文件的任務(wù)
    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()

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

大兴区| 东兰县| 兴化市| 马龙县| 望都县| 台北市| 丹阳市| 公主岭市| 白银市| 根河市| 镇原县| 莫力| 平遥县| 天水市| 来宾市| 长岛县| 海盐县| 伊宁县| 信阳市| 西城区| 蓝山县| 方山县| 丘北县| 临沂市| 五寨县| 灵宝市| 高雄市| 张家港市| 白沙| 栾川县| 东光县| 高邮市| 吴堡县| 衢州市| 百色市| 尖扎县| 玉山县| 车险| 禹州市| 雅安市| 平湖市|