【python基礎】十八、Python process 進程

進程 線程 協程

併發: 一個cpu, 輪流交替進行多線程
並行: 多個cpu, 同時執行,或 同時併發執行

進程 > 線程 > 協程 > 生成器

都可以實現多任務: 與特點有關

  • 任務比較多 用進程
  • 爬蟲 用線程 或 協程

進程(Process),操作系統結構的基礎,
曾經,面向進程設計的計算機結構中,進程就是程序的基本執行實體.(一個c)
當代,面向線程設計的計算機結構中,進程是線程的容器
* 優點
* 缺點

  • linux下 使用 fork 函數創建進程 os模塊的fork
  • windows 使用 multiprocessing模塊
  • 多進程 能否 訪問 同一個全局變量?

    • 能, 僅僅 複製 全局變量 到自己進程, 不共用
  • 耗時用 線程 - 下載

  • 計算用 進程 - 運算

import os
import time
from multiprocessing import Process

n = 5   #


def download(t):
    global n    # 只是取到全局n的初始值, 不與task_2 共用
    while True:
        n -= 1.8
        print(' -- SonProcess Task 1', os.getpid(), '-', os.getppid(), 'n:', n)
        time.sleep(t)


def getfile(t):
    global n
    while True:
        n += 0.75
        print(' -- SonProcess Task 2', os.getpid(), '-', os.getppid(), 'n:', n)
        time.sleep(t)


if __name__ == '__main__':
    print('MainProcess', n)
  download# 錯的
    p_1 = Process(target=download, args=(1,))     # 進程的 聲明
    p_2 = Process(target=getfile, args=(2,))

    p_1.start()     # 進程的 祁東
    p_2.start()
    while n >= 0:
        n -= 1
        print('MainProcess', n)     # 此時共3個進程: 主進程 子進程1 2
        time.sleep(2)
    p_2.terminate()     # 子進程的 關閉
    p_1.terminate()

    # 主進程 運行到此, 關閉

自定義進程

import random
from multiprocessing import Process
from time import sleep


class MyProcess(Process):

    def __init__(self, c_name):  # 如果想 傳入參數
        super(MyProcess, self).__init__()
        self.cname = c_name

    # 重寫 run 方法
    def run(self):
        n = 1
        while True:
            t = random.choice([0.3, 0.5, 0.8, 1])
            print('進程:{} -- n: {} [{}] -- t:'.format(self.name, n, self.cname), t)
            n += 1
            sleep(t)
            # self.name 自動命名


if __name__ == '__main__':
    p0 = MyProcess('尚尚')
    p1 = MyProcess('唐唐')

    p0.start()
    p1.start()

pool

子進程數量不多-> multiprocess 的 Process 動態生成即可
上千個子進程 -> multiprocess 的 pool 方法

初始化pool 指定 最大進程數, 新請求提交, 自動創建進程.
進程數達到最大值, 該請求等待 ( 網盤 多個文件同時下載)

阻塞式: 添加一個,執行一個. 執行結束後 返回個啥  
非阻塞式: 一起添加到隊列,立刻返回. 執行結束後, 回調 攜帶結果  

pool.apply_async()  非阻塞模式   一起來
pool.apply()        阻塞模式    一個一個來
def task_1(task_name):
    return retu_str


def call_back(n): 
    pass

if __name__ == '__main__':
    pool = Pool(4)

    tasks = ['吃飯', '睡覺', '打豆豆', '看書', '打代碼', '啪啪啪-2', '吃飯飯2', '睡覺覺2', '打豆豆豆豆', '看書書', '打代碼碼碼', '啪啪啪']
    for i in tasks:
        # pool.apply()
        pool.apply_async(task_1, args=(i,), callback=call_back)  # 非阻塞 異步

    # 進程池 依賴於 主進程, 阻止main結束
    pool.close()  # 進程池 任務 結束
    pool.join()  # 阻止 主進程 結束

進程間通信 Queue隊列

後面筆記 就亂寫了, 貼代碼吧

from multiprocessing import Queue
q = Queue(8)
q.put()
q.get()
q.full()
q.empty()
q.put_nowait()
q.get_nowait()
# queue
import random
import time
from multiprocessing import Queue, Process

def download(q):
    for i in range(100):
        t = random.random() * 2
        f = str(i) + '.jpg'
        print('- 正在下載 -- ', f)
        time.sleep(t)
        q.put(f)
        print('-- 下載完成 -- ', f, ' 用時:', round(t, 2), 's')


def getfile(q):
    while True:
        if not q.empty():
            time.sleep(1)
            print('--- 獲取文件 -- ', q.get(), ' 剩餘文件', q.qsize(), '個')


if __name__ == '__main__':
    q = Queue(5)

    p_1 = Process(target=download, args=[q])  # 進程的 聲明
    p_2 = Process(target=getfile, args=[q])

    p_1.start()
    p_2.start()

    p_1.join()
    p_2.join()
    p_2.terminate()  # 子進程的 關閉
    p_1.terminate()

    # queue 依賴 主進程 運行到此, 釋放了q

在b站學習中

個人主頁

學習鏈接

歡迎 批評 指正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章