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