進程 線程 協程
併發: 一個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