20-python的多進程 多進程使用queue共享數據 自定義進程類


一、前情知識了解

二、python的多進程

三、python 多進程之間如何實現數據共享

四、自定義進程類

 

一、前情知識了解

1.什么是程序和系統

一個系統一般由多個程序構成。如:win10系統由進程管理程序、內存管理程序、n個驅動程序等構成

2.操作系統的作用:與硬件交互

3.任務:打開某個軟件。瀏覽網頁、下載電影。。。每個應用呈現被成為一個任務

4.單任務:只能有一個任務在進行(DOS系統)

5.多任務:可以有多個任務同時進行(WIN10)

6.CPU時間片:程序的執行依賴CPU,CPU把自己進行時間上的分割,每個程序輪流占用CPU。時間片一般是切換時間的100倍

7.分時操作系統:以時間片輪轉的方式,讓一台計算機為多個終端服務

8.進程:應用程序的動態執行過程

  進程的狀態:運行、等待、就緒

  正在運行的軟件,就是正在運行的進程。(一個軟件只有運行,才能生成進程,可生成1-n個進程。不運行就是個軟件,就不能叫做進程)

  進程的執行過程:啟動--》軟件代碼要加載到內存--》CPU為進程建立檔案(PID:進程的唯一標識)--》等CPU的時間片--》執行--》退出

9.單核:同一時間,只能有一個程序在使用CPU

  比如說多個程序放在隊列中,按照某種算法讓不同的程序輪流執行,0.01us允許A程序,0.02us允許B程序

 

 

二、python的多進程(多個進程並發執行)

0.通過使用子進程而非線程有效地繞過了 全局解釋器鎖GIL(global interpreter lock)。 因此,multiprocessing 模塊允許程序員充分利用給定機器上的多個處理器。 它在 Unix 和 Windows 上均可運行

1. 在python中,執行一個python腳本,就會創建一個進程

  •     python中獲取當前進程的id: os.getpid()
  •     手動終止進程:taskkill /f /PID 89888

2. python中如何創建多進程

  • 標准庫 :multiprocessing庫中Process

         from multiprocessing import Process

3. 如何創建子進程

    在主進程中通過Process類創建的進程對象就是子進程

舉個栗子:

import logging
import os
import time
from multiprocessing import Process

logging.basicConfig(level=logging.INFO)


class MyClass:
    """Process 1"""

    def __init__(self, *, name: str, age: int) -> None:
        """Init"""

        self.name = name
        self.age = age
        self.logger = logging.getLogger("MyProcess")

    def info(self, address: str) -> None:
        """Info"""

        self.logger.info("This is info...")
        basic_info = (self.name, self.age)
        for _ in range(2):
            time.sleep(1)
            print(f"Basic info is {basic_info}, address{address}.")

    def sing(self) -> None:
        """Sing"""

        self.logger.info("This is sing...")
        for _ in range(3):
            time.sleep(1)
            print(f"{self.name} is singing《reality》now.")


def validation_daemon():
    """Validate daemon"""

    my_process = MyClass(name="zhangsan", age=18)
    start_time = time.time()
    # Creat process
    # daemon=False, 主進程要等待子進程,daemon=True,主進程結束,程序就結束了,不會等待子進程
    # 這里主進程運行了0.003s后,還會繼續等待子進程
    process_1 = Process(target=my_process.info, args=("beijing road",), daemon=False)
    process_2 = Process(target=my_process.sing, daemon=False)
    print(f"This is Process, pid is {os.getpid()}")

    # Start
    process_1.start()
    process_2.start()
    end_time = time.time()
    print(f"Run time is {end_time - start_time}")  # 主進程最后一行,運行完主進程結束,但是是否等待子進程,取決daemon參數設置


def validation_join():
    """Validate join"""

    my_process = MyClass(name="LiSi", age=20)
    start_time = time.time()
    # Creat process
    process_1 = Process(target=my_process.info, args=("beijing road",), daemon=True)
    process_2 = Process(target=my_process.sing, daemon=True)
    print(f"This is Process, pid is {os.getpid()}")

    # Start
    process_1.start()
    process_2.start()
    # join,主進程等待子進程結束后,再執行后面的代碼,那么主進程的運行時間變長(包含等待子進程運行的時間)
    process_1.join()
    process_2.join()
    end_time = time.time()
    print(f"Run time is {end_time - start_time}")

def single_process():
    """Single process """

    my_process = MyClass(name="LiSi", age=20)
    start_time = time.time()
    my_process.info(address="beijin road")
    my_process.sing()
    end_time = time.time()
    print(f"Run time is {end_time - start_time}")


if __name__ == '__main__':
    validation_daemon()
    validation_join()
    single_process()  # 單進程執行效率低,時間長

 

總結:

1.啟動進程:process.start()

2.Process 的參數daemon(daemon:守護進程;后台程序)

  • daemon=True 表示主進程執行完,不會等待該子進程
  • daemon=False 表示主進程執行完,會等待該子進程執行完畢 再退出

 3.Process的參數join

  • p1.join()表示:主進程會等待子進程p1執行完,再執行剩下的代碼

 

三、python 多進程之間如何實現數據共享

1.首先來看一下,多進程之間能否直接操作全局變量進行數據共享?

思路:

  • 創建一個全局變量
  • 創建2個子進程,分別對這個全局變量進行操作
  • 查看全局變量值 是否發生變化(2個子進程對該全局變量的操作是否成功?)
"""多進程的全局變量"""


from multiprocessing import Process CONSTANT = 10 def funtion_1(): """Funtion 1""" global CONSTANT CONSTANT += 1 print(f"Funtion_1 constant is {CONSTANT}") def funtion_2(): """Function 2""" global CONSTANT CONSTANT += 2 print(f"Funtion_2 constant is {CONSTANT}") def funtion_test(): """Test""" f1_process = Process(target=funtion_1) f2_process = Process(target=funtion_2) f1_process.start() f2_process.start() if __name__ == '__main__': funtion_test() print(f"The main process constant is {CONSTANT}") #10 ,因為多個進程之間的資源是不可分享的,因為各個進程是獨立占用內存的

結果:全局變量沒有發生變化。

結論:

每創建一個進程,CPU都會單獨分配資源;所以呢,多個進程是不會共享全局變量的

 

2.如何實現多進程之間數據共享----多個進程共享主進程中創建的隊列

法:multiprocessing 庫中的Queue模塊,即用 隊列queue共享數據

思路:

  • 主進程創建隊列
  • 然后把隊列作為參數傳到各個子進程中
  • 各子進程對隊列中的數據進行操作

隊列的操作:

  • queue.get() 表示獲取隊列中的數據
  • queue.put(X) 表示將數據X存入隊列中

實現如下:

"""Queue"""

# 多進程中如何使用隊列queue共享數據?----多個進程共享主進程中創建的隊列
# 方法:
# 主進程創建隊列,然后把隊列作為參數傳到各個子進程中即可

from multiprocessing import Process, Queue


def fun1(queue):
    """Fun 1
    :param queue:  Queue
    """
    value = queue.get()
    value += 1
    queue.put(value)
    print(f"Fun 1 value is {value}")


def fun2(queue):
    """Fun 2
    :param queue:  Queue
    """
    value = queue.get()
    value += 2
    queue.put(value)
    print(f"Fun 2 value is {value}")


def funtion_multi_process():
    queue = Queue()
    queue.put(0)
    f1_process = Process(target=fun1, args=(queue,), daemon=False)
    f2_process = Process(target=fun2, args=(queue,), daemon=False)
    f1_process.start()
    f2_process.start()
    f1_process.join() # 這里使用join()進行阻塞主進程的話,上面的daemon參數就可以不設置了
    f2_process.join()
    print(f"Main process value is {queue.get()}")


if __name__ == '__main__':
    funtion_multi_process()

 

四、自定義進程類

1.自定義類繼承multiprocessing的Process類

"""自定義進程類"""

import multiprocessing


class MyMultiProcess(multiprocessing.Process):
    """Class for Multi Process."""

    def __init__(self, user: str):
        """Init"""
        super().__init__()
        self.user = user

    def run(self):
        num = 10
        for _ in range(5):
            num += 1
        print(f"{self.user}'s number is {num}")


if __name__ == '__main__':
    # Creat an object
    p1 = MyMultiProcess("zhangsan")
    p2 = MyMultiProcess("lisi")
    p1.start()
    p2.start()

 


免責聲明!

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



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