Python進(jìn)程

進(jìn)程

  • 概念:指的時(shí)運(yùn)行的程序以及運(yùn)行時(shí)用到的資源這個(gè)整體稱(chēng)之為進(jìn)程

經(jīng)典三狀態(tài):

  • 就緒態(tài):運(yùn)行的條件都已經(jīng)慢去,正在等待cpu執(zhí)行(cpu分配時(shí)間片執(zhí)行,切換到執(zhí)行態(tài))
  • 執(zhí)行態(tài):cpu正在執(zhí)行其功能(時(shí)間片用完就切換到就緒態(tài))
  • 等待態(tài):在運(yùn)行的代碼中有需要等待某些條件(數(shù)據(jù)input()、時(shí)間sleep())阻塞等待,如果條件滿足,切換到就緒態(tài)

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

    pro = multiprocessing.Process(target= 函數(shù)名, args=(參數(shù)列表元組))
    pro.start()

主進(jìn)程阻塞等待子進(jìn)程退出

  pro.join(time)  表示主進(jìn)程最多等子進(jìn)程time秒
  pro.is_alilve()  判斷子進(jìn)程是否存活
  pro.terminate() 直接終止子進(jìn)程(信號(hào)有延時(shí))-->.join()
  pid:當(dāng)前進(jìn)程的進(jìn)程號(hào)(ps aux,ps -eflgrep)
  getpid()子進(jìn)程的pid,getppid() 子進(jìn)程的父進(jìn)程的pid

進(jìn)程間是獨(dú)立的地址空間,所以不共享全局變量

進(jìn)程間通信Queue

創(chuàng)建隊(duì)列

q = multiprocessing.Queue(參數(shù)表示隊(duì)列最大長(zhǎng)度)
q.put()  存放數(shù)據(jù)
q.get()  取出數(shù)據(jù)
q.full()  判斷是否滿了
q.empty() 判斷是否空了
q.qsize() 獲取隊(duì)列長(zhǎng)度

進(jìn)程池Pool

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

    p = multiprocessing.Pool(參數(shù)表示進(jìn)程的最大數(shù)量)
    # 添加任務(wù)
    p.apply  是阻塞添加任務(wù),會(huì)等待添加的任務(wù)執(zhí)行完成才會(huì)繼續(xù)往下執(zhí)行
    p.apply_async  非阻塞的任務(wù)添加,只管添加任務(wù),不等任務(wù)結(jié)束
    # 關(guān)閉進(jìn)程池
    p.close()
    p.terminate()  強(qiáng)制終止進(jìn)程池中所有的正在執(zhí)行的進(jìn)程任務(wù)
    # 等待所有任務(wù)執(zhí)行完成
    p.join()  保持主進(jìn)程存活,等待所有子進(jìn)程完成

注意事項(xiàng)

  • 如果需要在進(jìn)程池中使用進(jìn)程間通信Queue,不要使用multiprocessing.Queue()(要求是通過(guò)繼承的方式創(chuàng)建的進(jìn)程),應(yīng)該使用multiprocessing.Manager.Queue()
  • .close() .terminate()之后一般都建議更上 .join(); .join()之前一定要調(diào)用 .close() .terminate()

進(jìn)程與線程的對(duì)比

定義的不同

  • 進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位

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

區(qū)別

  • 一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程
  • 線程的劃分尺度小于進(jìn)程(資源比進(jìn)度少),使得多線程程序的并發(fā)性高
  • 進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大的提高了程序的運(yùn)行效率
  • 線程不能獨(dú)立執(zhí)行,必須依存在進(jìn)程中
  • 可以將進(jìn)程理解為工廠中的一條流水線,而其中的線程就是這個(gè)流水線上的工人

優(yōu)缺點(diǎn)

進(jìn)程和線程在使用上各有優(yōu)缺點(diǎn),線程執(zhí)行開(kāi)銷(xiāo)小,但不利于資源的管理個(gè)保護(hù);而進(jìn)程相反

進(jìn)程簡(jiǎn)單的實(shí)現(xiàn)文件夾copy器

import os
import time
import multiprocessing


def copy_file(src_path, dest_path, file_name, q):
    """拷貝文件的函數(shù)"""
    f = open(src_path + "/" + file_name, "rb")
    f1 = open(dest_path + "/" + file_name, "wb")
    f1.write(f.read())
    f.close()
    f1.close()
    # 將文件名加入隊(duì)列
    q.put(file_name)


if __name__ == '__main__':
    # 使用多進(jìn)程 完成對(duì)指定目錄下的文件拷貝
    # 1.用戶輸入目錄-->源目錄
    src_path = input("輸入你要拷貝的文件名稱(chēng):")
    # 2.創(chuàng)建一個(gè)新的目錄 存放拷貝之后的文件數(shù)據(jù)
    dest_path = src_path + "[復(fù)件]"
    os.mkdir(dest_path)
    # 3.獲取指定目錄下的所有文件信息
    file_list = os.listdir(src_path)
    # 子進(jìn)程再?gòu)?fù)制完成文件之后 將文件名寫(xiě)入隊(duì)列 父進(jìn)程從隊(duì)列中取出已經(jīng)完成的文件列表
    q = multiprocessing.Queue()
    # 4.傳入 源目錄 目的目錄 文件名 使用一個(gè)子進(jìn)程完成該文件的拷貝
    for file in file_list:
        pro = multiprocessing.Process(target=copy_file, args=(src_path, dest_path, file, q))
        pro.start()
    # 顯示拷貝進(jìn)度模塊
    count = 0
    while True:
        file_name = q.get()
        count += 1
        print("\r 當(dāng)前的進(jìn)度%.2f %%" % ((count / len(file_list)) * 100), end="")
        time.sleep(0.6)
        if count == len(file_list):
            print("拷貝完成")
            break
# 進(jìn)程小坑
import multiprocessing


def write():
    print("11")


print("123456")
if __name__ == '__main__':
    pro1 = multiprocessing.Process(target=write)
    pro1.start()


-----運(yùn)行結(jié)果-----
123456
123456
11
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容