python多任務處理


多任務解析

  • 什么叫“多任務”呢?簡單地說,就是操作系統可以同時運行多個任務。 現在,多核CPU已經非常普及了,但是,即使過去的單核CPU,也可以執行 多任務。由於CPU執行代碼都是順序執行的,那么,單核CPU是怎么執行多 任務的呢?

  • 其實就是操作系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務 2,任務2執行0.01秒,再切換到任務3,執行0.01秒……這樣反復執行下去。 表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太 快了,我們感覺就像所有任務都在同時執行一樣。

  • 真正的並行執行多任務只能在多核CPU上實現,但是,由於任務數量遠遠多 於CPU的核心數量,所以,操作系統也會自動把很多任務輪流調度到每個核 心上執行。

多任務表現形式

  • window下打開任務管理器可以很清晰看到多個進程在同時執行任務,qq、微信等都是已進程的形式寄存在window下。大多我們在寫一些控制台程序真正執行的時候都是以進程調度。

  • 在linux下以fork的形式創建進程,簡單寫個實例:

多次fork創建,進程數會已指數倍增長。

`
import os
import time

num = 0
# 主進程創建了一個子進程
ret = os.fork()
if ret == 0:
        num+=1
        print('ret = 0,num=%d',num)
else:
        time.sleep(1)
        print('he,num=%d',num)

# 主進程會再次創建一個子進程,上面的子進程也會創建一個子進程
ret = os.fork()
if ret ==0:
        print('aaaaa')
else:
        print('bbbb')
`

python中多進程

如果你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。由於Windows沒有fork調用,由於Python是跨平台的,當然也應該提供一個跨平台的多進程支持。 multiprocessing模塊就是跨平台版本的多進程模塊。 multiprocessing模塊提供了一個Process類來代表一個進程對象

進程池調度

- 每次指定幾個進程同時執行任務

`
from multiprocessing import Pool
import os
import time


def worker(num):
        print('pid = %d,num = %d'%(os.getpid(),num))
        time.sleep(2)


pool = Pool(3)

for i in range(10):
        print('%d'%i)
        pool.apply_async(worker,(i,))

pool.close()
pool.join()

`
  • apply_async非阻塞式調度,apply阻塞式調度

進程間通訊

  • 任何進程間資源都是獨立的,所有一切都是不可以共享的。實現資源共享、進程間通訊比較常用的方式就是Queue。

  • 使用Queue可以解決Process創建的進程之間的通訊,但是無法解決進程池中進程之間通訊。

  • 進程池進程之間的通訊需要使用Manager.Queue()創建的隊列。

實現基於多進程的文件拷貝

`
# coding:utf-8

from multiprocessing import Pool,Manager
import os

def CopyFile(oldPath,newPath,fileName,queue):
    fr = open(oldPath+'/'+fileName)
    fw = open(newPath+'/'+fileName,'w')

    # 當然如果是較大文件時,不要一次性讀寫
    content = fr.read()
    fw.write(content)

    fr.close()
    fw.close()

    queue.put(fileName)

def Main():
    oldPath = input('please input folder path:')
    newPath = oldPath+'-backups'
    os.makedirs(newPath)

    fileNames = os.listdir(oldPath)

    pool = Pool(5)
    queue = Manager().Queue()

    for name in fileNames:
        pool.apply_async(CopyFile,args=(oldPath,newPath,name,queue))

    num = 0
    allNum = len(fileNames)
    while num<allNum:
        queue.get()
        num += 1
        copyRate = num/allNum
        print('\r當前copy進度:%.2f%%'%(copyRate*100),end='')

    print('\n 已完成copy!')

if __name__ == '__main__':
    Main()
`

GitHub:基於多進程的文件拷貝


免責聲明!

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



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