併發編程

 

建立進程

建立進程-帶傳參

from multiprocessing import Process
import time

def func(args):
print('in func %s'%args)

if __name__ == '__main__':
p=Process(target=func,args=(3,))
print('in main')
p.start()
time.sleep(2)
print('end')

建立線程

 

from threading import Thread
def func2(args):
print('in func2 %s'%args)

if __name__ == '__main__':
t=Thread(target=func2,args=(4,))
t.start()


from threading import Thread
def func(n):
print('in func %s'%n)

t=Thread(target=func,args=(5,))
t.setDaemon(True) #setDemon 加入將主線程設置爲守護線程,那麼主線程結束,無論子線程有沒有結束,都會自動結束
t.start()
print('主線程')

  

開啓多個子進程

from multiprocessing import Process
def func(num):
print('in func %s'%num)

if __name__ == '__main__':
p_l=[]
for i in range(10):
p=Process(target=func,args=(i,))
p.start()
print(p.is_alive()) #判斷子進程是否在執行
p_l.append(p)
for p in p_l:
p.join() #join方法,阻塞,使子進程執行結束完畢,再繼續執行,不是守護進程哈哈哈!
print('主進程代碼執行結束')

  

from threading import Thread
import os
def func(n):
print('in func %s'%n)

t1=Thread(target=func,args=(3,))
t2=Thread(target=func,args=(4,))
t1.start()
t2.start()

print('主線程pid',os.getpid(),os.getppid())

 

守護進程

守護子進程

from multiprocessing import Process
import os,time,random

def task():
print('%s is running' %os.getpid())
time.sleep(2)
print('%s is done' %os.getpid())

#守護進程內沒法再開啓子進程,不然拋出異常
# p = Process(target=time.sleep, args=(3,))
# p.start()

if __name__ == '__main__':
p=Process(target=task)
p.daemon = True #一、必須在p.start()以前
p.start()
print('主')
# 結果:
# 主
# 緣由是:主進程程序啓動執行到p子進程,因爲子進程須要開闢內存空間,因爲須要耗費時間,因此主進程會首先輸出「主」,
# 因爲主進程執行完畢,那麼守護子進程p也就被幹掉了,隨之主進程也就退出了

若是將上一句改成
if __name__ == '__main__':
p=Process(target=task)
p.daemon = True #一、必須在p.start()以前
p.start()
p.join()
print('主')

# 執行結果:
# 14732 is running
# 
# 14732 is done
# 主

守護進程和非守護進程並存

from multiprocessing import Process
from threading import Thread
import time,os
def foo():
print(123)
time.sleep(1)
print("end123")

def bar():

print(456)
time.sleep(3)
print("end456")


if __name__ == '__main__':
p1=Process(target=foo)
p2 = Process(target=bar)

p1.daemon=True
p1.start()
p2.start()
print("main-------")
# 結果:
# main-------
# 456
# end456
# 緣由以下:因爲p1,p2都是子進程,須要開闢內存空間,須要耗費時間,因此會優先輸出主進程「main」,
# 因爲p1是守護子進程,p2是非守護子進程,當主進程執行完畢(注意之類主進程尚未退出,由於還有p2非守護進程),
# p1守護進程也就退了,可是還有一個p2非守護進程,因此p2會執行本身的代碼任務,當p2執行完畢,那麼主進程也就退出了,
# 進而整個程序就退出了

 

守護線程

守護子線程

from multiprocessing import Process
from threading import Thread
import os,time,random

def task():
# t=Thread(target=time.sleep,args=(3,))
# t.start()
print('%s is running' %os.getpid())
time.sleep(2)
print('%s is done' %os.getpid())

if __name__ == '__main__':
t=Thread(target=task)
t.daemon = True
t.start()
print('主')

# 結果:
# 18704 is running
# 主
# 緣由是:
# 在執行到守護子線程t,因爲主線程子線程通用一塊內存,因此不存在不一樣進程建立各自空間,
# 因此就先輸出子進程的執行任務代碼,因此輸出print(‘%s is running’ %os.getpid()),因爲time.sleep(2),
# 因此就會執行主線程「main」,而後主線程執行完畢,那麼即便2秒事後,因爲主線程執行完畢,那麼子守護線程也就退出了,
# 因此 print(‘%s is done’ %os.getpid())就不會執行了。

守護子線程與非守護子線程並存

from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123")

def bar():
print(456)
time.sleep(3)
print("end456")

if __name__ == '__main__':
t1=Thread(target=foo)
t2 = Thread(target=bar)

t1.daemon=True

t2.start()
t1.start()
print("main-------")

# 結果:
# 456
# 123
# main-------
# end123
# end456
# 
# 緣由是:
# t1是守護子線程,t2非守護子線程,跟主線程使用一塊內存,因此會輸出t1,t1子線程的任務代碼,因此執行456,
# 123因爲t1,t2都有睡眠時間,因此執行主線程代碼,而後對主線程來講,
# 運行完畢指的是主線程所在的進程內全部非守護線程通通運行完畢,主線程纔算運行完畢,因此會執行t1,t2睡眠後的任務代碼,
# 而後程序退出。 咱們會問爲何t1守護子線程,也會執行sleep後的代碼,不是說主線程代碼執行完畢,
# 守護線程就被幹掉了嗎?這裏要注意是對主線程來講,運行完畢指的是主線程所在的進程內全部非守護線程通通運行完畢,
# 主線程纔算運行完畢,當時t2還沒執行完畢

 

開啓進程池

不一次性出來結果

import os
from multiprocessing import Pool
import time

def func(num):
time.sleep(2)
print('in func %s'%num)

if __name__ == '__main__':
p=Pool(5)
for i in range(20):
p.apply_async(func,args=(i,)) #apply_async表示五個一出,換成apply表示爲同步出,一個一個出
p.close()
p.join()

一次性出來執行結果

from multiprocessing import Pool
import time
def haha(num):
print('in func %s'%num)
return True

if __name__ == '__main__':
p=Pool(5)
p_l=[]
for i in range(20):
ret=p.apply_async(func=haha,args=(i,)) #進程池使用func,開啓進程使用target
p_l.append(ret)
for ret in p_l:
print(ret.get()) #若是haha這個函數有返回值,則可經過ret.get()獲取返回值,使用p_l=[]這種方式,能夠去掉join,close,
           等待全部的任務執行完畢再取出結果。 #join和get的區別在於:join等待全部的進程執行完畢就用join,若想提升效率,執行一個進程就出來一個結果,就用get().若是函數有返回值就用get()方法。

  

 

開啓線程池

from concurrent.futures import ThreadPoolExecutor
import time

def sayhello(a):
print("hello: "+a)
time.sleep(0.1)

def main():
seed=["a","b","c"]
start1=time.time()
for each in seed:
sayhello(each)
end1=time.time()
print("time1: "+str(end1-start1))
start2=time.time()
with ThreadPoolExecutor(3) as executor:
for each in seed:
executor.submit(sayhello,each)
end2=time.time()
print("time2: "+str(end2-start2))
start3=time.time()
with ThreadPoolExecutor(3) as executor1:
executor1.map(sayhello,seed)
end3=time.time()
print("time3: "+str(end3-start3))

if __name__ == '__main__':
main()
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息