程序、執行緒、協程(程序篇)
阿新 • • 發佈:2018-12-23
程序篇
(最近在學習程序,看視訊的時候做了一個總結)
現代作業系統(Window、Mac OS X、Unix、Linux)都支援‘多工’
什麼叫做多工呢?
--> 作業系統可以同時執行多個任務
-->單核CPU執行多工是時間片輪轉實現的(作業系統輪流讓各個任務交替執行)
-->多核CPU,每個核心執行一個程序,如果程序比較多,那就有可能其中一個交替執行;但是程序數量一定比核心數多,所以作業系統會自動把很多工輪流排程到每個核心上執行
併發:看上去一起執行,任務數多餘CPU核心數
並行:真正一起執行,任務數小於等於CPU核心數
實現多工的方式:
1.多程序模式
2.多執行緒模式
3.協程模式
4.多程序+多執行緒模式
# 多工同時進行
# 在寫多程序程式碼的時候要先呼叫一個多程序類下的一個程序函式 from multiprocessing import Process import time, os # 定義一個子程序函式,傳一個引數 def run(string): # 寫一個死迴圈用來測試 while True: # 列印子迴圈的資訊 # getpid()當前程序的ID號 #getppid()當前程序的父程序的ID號 print('zpstu----{}----{}----{}'.format(string, os.getpid, os.getppid())) time.sleep(1) if __name__ == '__main__': print('主程序開始啟動了-{}'.format(os.getpid())) # 建立子程序,target指明程序執行的任務 p = Process(target=run, args=('zpatu',)) # 啟動程序 p.start()while True: print('zpstu is very good!') time.sleep(1)
# 程序、子程序、執行順序
'''
程序:對於作業系統而言,一個任務就是一個程序;程序是系統中程式執行和資源分配的基本單位i,每個程序都有自己的資料段、程式碼段、和堆疊段
'''
from multiprocessing import Process import time, os
def run(string):
print('子程序啟動')
# 等待兩秒
time.sleep(2)
print('子程序結束')
if __name__ == '__main__':
# 首先父程序啟動
print('父程序啟動')
# 建立子程序
p = Process(target=run, args=('zpstu',))
# 啟動程序
p = start()
# 等待子程序結束,在結束父程序
p.join() # join()必須要等子程序結束了,在執行父程序,不然就卡這裡了
print('父程序結束')
# 全域性變數在多個程序中不能共享
'''
父程序和子程序之間的資源是不能共享的,就算使用全域性global屬性,也是不能共享
這是因為:在子程序建立的時候,對全域性變數做了一個備份,所以num兩個變數就不是一個變數
'''
from multiprocessing import Process
from time import sleep
num = 100
def run():
print('啟動子程序')
global num # 這行程式碼就相當於num = 100
num += 1
print('子程序結束')
if __name__ == '__main__':
print('父程序開始')
p = Process(target=run)
p.start()
p.join()
print('父程序結束-->{}'.format(num))
# 啟動大量子程序
'''
這裡引入了程序池的概念
'''
from multiprocessing import Pool
import os,time,random
def run():
print('子程序{}啟動-->{}'.format(name, os.getpid()))
start = time.time()
time.sleep(random.choice([1, 2, 3]))
end = time.time()
print('子程序{}結束-->{}'.format(name, os.getpid()))
if __name__ == '__main__':
print('父程序啟動')
# 建立多個程序
# 程序池:便是可以同時執行的程序數量
# Pool預設大小是CPU核心數
pp = Pool(5)
for i in range(5):
# 建立程序,放入程序池統一管理(當你放入程序池的時候,程序便開始啟動了)
pp.apply_async(run, args=(i,))
# 再呼叫join之前,必須呼叫close,呼叫close之後就不能再繼續新增新的程序了
pp.close()
# 程序池物件呼叫join,他會等待程序池所有的子程序結束完畢再去結束父程序
pp.join()
print('父程序結束')
# 拷貝檔案(普通的拷貝檔案,下面有多程序的拷貝檔案)
import os, time
from multiprocessing import Pool
# 拷貝檔案的函式
def copyFile(rPath, wPath):
fr = open(rPath, 'rb')
fw = open(wPath, 'wb')
content = fr.read()
fw.write(content)
fr.close()
fw.close()
# 兩個檔案路徑
path = r'E:\code\aaa'
topath = r'E:\code\toFile'
# 讀取path下的所有檔案
fileList = os.listdir(path)
# 啟動for迴圈處理每一個檔案
start = time.time()
foe i in fileList:
copyFile(os.path.join(path, i), os.path.join(topath, i))
end = time.time()
print('總耗時:{:0.2}'.format(end-start))
# 多程序實現檔案拷貝
import os, time
from multiprocessing import Pool
def copyFile(rPath, wPath):
fr = open(rPant, 'rb')
fw = open(wPath, 'wb')
content = fr.read()
fw.write(content)
fr.close()
fw.close()
path = r'E:\code\aaa'
topath = r'E:\code\toFile'
if __name__ == '__main__':
fileList = os.listdir(path)
start = time.time()
for i in fileList:
# 拼接目錄
pp.apply_async(copyFile, args=(os.path.join(path, i)))
pp.close()
pp.join()
end = time.time()
print('總耗時{:0.2}'.format(end-start))
# 程序間通訊
from multiprocessing import Process, Queue
import os,time
def write(q):
print('啟動寫入子程序--{}'.format(os.getpid()))
for i in ['A', 'B', 'C', 'D', 'E']:
q.put(chr)
time.sleep(1)
print('結束寫入子程序')
def read(q):
print('啟動讀取子程序--{}'.format(os.getpid()))
while True:
value = q.get(True)
print('value = ', value)
print('結束讀取子程序') # 這行程式碼不會執行,因為死迴圈根本就出不來,只能強制結束它
if __name__ == '__main__':
# 父程序建立佇列,並傳遞給子程序
# 考錄佇列,拿出來一個就沒一個,也就是一個傳遞進去,一個拿出來
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
# pr程序內是一個死迴圈,無法等待結束,所以只能強行結束
pr.terminate()
print('父程序結束')