python 多進程

多進程多任務執行方法(調度算法)有時間片輪轉,優先級調度
* 併發:任務數大於核數,看上去是一起執行的
* 並行:任務數小於等於核數,是真正一起執行的

import osimport timeret=os.fork() #創建一個進程 原進程爲父進程,創建的稱子進程 父進程返回ret>0,子進程ret=0if ret==0: while True: print(‘1111’) time.sleep(1)else: while True: print(‘2222’) time.sleep(1)getpid,getppidos.getpid是獲取當前進程的pidos.getppid是獲取該進程的父進程的pid父子進程的優先順序父子進程的區別。代碼是同一份代碼但各自有各自的數據父進程不一定先執行,得看操作系統的調度算法
父進程結束以後子進程不受影響會繼續按部就班執行,各個進程之間相互獨立(針對fork來說的)

#fork()  fork可以創建子進程但不跨平臺只在Linux上用
import os
import time
g_num=100
ret = os.fork()
if ret==0:
    print("---process1---")
    g_num+=1
    print(g_num)
else:
    time.sleep(3)
    print("----process2----")
    print(g_num)     
#fork炸彈
while 1:
    os.fork()   

Process創建的進程中,主進程會等子進程結束之後才結束

#Process 跨平臺式創建子進程方法
from multiprocessing import Process
import time

def test():
    while True:
        print("--test--")
        time.sleep(1)
qq=Process(target=test)
qq.start()
qq.join() #等待子進程結束之後才繼續往下走 執行while   叫做 堵塞
             #p.join(3)  如果3秒內進程結束了,則正常執行,若未結束,則不管子進程,父進程繼續向下執行
qq.terminate()  #終結進程
while True:
    print("---2---")
    time.sleep(1)

#另外一種創建子進程的方式
class MyProcess(Process):
    def run(self):
        for i in range(5):
            print("---1---")
            time.sleep(1)
qq=MyProcess() #調用父類,調用重寫的父類的子方法
qq.start()
qq.join()
print("happy ending")

進程池(池 緩存緩衝數據)
用固定的進程數,同時執行多個任務 如3個進程執行10個任務 前些任務完成後不用再創造進程而是後面的任務再放到進程中,提升了性能
主進程一般用來等待,子進程進行執行任務

import time
from multiprocessing import Pool
import os

def work(num):
    for i in range(5):
        print("==pid=%d==num=%d"%(os.getpid(),num))
        time.sleep(1)
p=Pool(3) #創建3個進程的進程池,其中3個進程一起執行
#注意,當其中一個進程完成一個任務以後,等待的任務會進入這個剛完成任務的進程
for i in range(10): #一次性放進10個任務
    print("---%d---"%i)
    p.apply_async(work,(i,)) #非堵塞方式,任務直接全部添加
    #p.apply #堵塞的方式運行的,先添加一個任務然後暫停,去進程池裏執行任務
p.close()#關閉進程池,不能再添加任務,幾乎不用
p.join()#
進程間通信

進程a給進程b再給進程c
from multiprocessing import Queue,Process
import time,os

def work_put(q):
    print("This is put")
    for i in ["a","b","c"]:    
        q.put(i)
        print("%s has been put in"%i)
def work_get(q,q1):
    print("This is get")
    while True:
        if q.empty():
            print("NULL")
            break
        else:
            a = q.get()
            q1.put(a)
            print("%s has been taken out"%a)
def work_gget(q1):
    while True:
        if q1.empty():
            print("NULL")
            break
        else:
            b = q1.get()
            print("%s has been dsadsa"%b)
if __name__ == '__main__':
    q=Queue()
    q1=Queue()
    pp=Process(target=work_put,args=(q,)) #傳進程名稱
    gg=Process(target=work_get,args=(q,q1))
    gp=Process(target=work_gget,args=(q1,))
    pp.start()
    pp.join()    
    gg.start()
    gg.join()
    gp.start()
    gp.join()
進程池pool中進程的通信,需要import Manager(),然後創建隊列的時候,用q=Manager().Queue()
文件拷貝

#-*- coding=utf-8 -*-
from multiprocessing import Pool,Manager
import os

def CopyFileTask(name,oldFolderName,newFolderName,queue):
    fr=open(oldFolderName+"/"+name)
    fw=open(newFolderName+"/"+name,"w")
    content=fr.read()
    fw.write(content)
    fr.close()
    fw.close()
    queue.put(name)
def main():
    oldFolderName=input("Please input the name you want to copy: ")
    newFolderName=oldFolderName+"-復件"

os.mkdir(newFolderName)
filenames = os.listdir(oldFolderName)

pool=Pool(5)
queue=Manager().Queue()
for name in filenames:
    pool.apply_async(CopyFileTask,args=(name,oldFolderName,newFolderName,queue))

num=0
allNum=len(filenames)
while True:
    queue.get()
#        if not queue.empty():
        num+=1
        rate = num/allNum
#        print("\rcopy的進度是%.2f"%rate,end="")
#        else:
#            break

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