1. 程式人生 > >程序、執行緒、協程(程序篇)

程序、執行緒、協程(程序篇)

程序篇 

           (最近在學習程序,看視訊的時候做了一個總結)

  現代作業系統(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('父程序結束')