['建立進程2方式種',
'進程對象屬性:join方法,守護進程obj.daemon=True,obj.pid, obj.name, obj.terminate(),obj.is_alive()等 '
'os.getpid,os.getppid',
'互斥鎖(Lock())',
'殭屍進程與孤兒進程',
'內存空間物理上隔離']
併發的本質:切換+保持狀態
1、同一個程序執行屢次是多個進程
每個進程有一個PID
import os
os.getppid() #父的pid (pycharm.exe)#cmd 中 pyhon 路徑 父的pid(cmd.exe)
os.getpid() #本身的pid (python.exe)
併發的本質:切換+保持狀態
1、同一個程序執行屢次是多個進程
每個進程有一個PID
import os
os.getppid() #父的pid (pycharm.exe)#cmd 中 pyhon 路徑 父的pid(cmd.exe)
os.getpid() #本身的pid (python.exe)
2、開啓子進程的兩種方式
windows (createprocess) 建立子進程時子輩除了拷貝父輩的信息還建立了些本身的東西
unix (fork) 建立子進程時拷貝父輩的信息, 子進程的初始狀態和父輩一致
windows (createprocess) 建立子進程時子輩除了拷貝父輩的信息還建立了些本身的東西
unix (fork) 建立子進程時拷貝父輩的信息, 子進程的初始狀態和父輩一致
第一種(比較經常使用)
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(3)
print('%s is done' %name)
if __name__ == '__main__':
# 在windows系統之上,開啓子進程的操做必定要放到這下面
# Process(target=task,kwargs={'name':'egon'}) #兩種傳參方式皆可
p=Process(target=task,args=('egon',)) #兩種傳參方式皆可
p.start() # 向操做系統發送請求,操做系統會申請內存空間,把父進程的數據拷貝給子進程,做爲子進程的初始狀
print('======主')
第二種
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__init__() #Process在init裏面有相應設置,要遺傳下來,不然報錯
self.name=name
def run(self):
print('%s is running' %self.name)
time.sleep(3)
print('%s is done' %self.name)
if __name__ == '__main__':
p=MyProcess('egon')
p.start() #p.start()調用了類中的run()方法(規定)
print('主')
from multiprocessing import Process
import time
def task(name):
print('%s is running' %name)
time.sleep(3)
print('%s is done' %name)
if __name__ == '__main__':
# 在windows系統之上,開啓子進程的操做必定要放到這下面
# Process(target=task,kwargs={'name':'egon'}) #兩種傳參方式皆可
p=Process(target=task,args=('egon',)) #兩種傳參方式皆可
p.start() # 向操做系統發送請求,操做系統會申請內存空間,把父進程的數據拷貝給子進程,做爲子進程的初始狀
print('======主')
第二種
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__init__() #Process在init裏面有相應設置,要遺傳下來,不然報錯
self.name=name
def run(self):
print('%s is running' %self.name)
time.sleep(3)
print('%s is done' %self.name)
if __name__ == '__main__':
p=MyProcess('egon')
p.start() #p.start()調用了類中的run()方法(規定)
print('主')
3、進程的內存空間相互隔離
from multiprocessing import Process
import time
x=1000
def task():
time.sleep(3)
global x
x=0
print('兒子死啦',x)
from multiprocessing import Process
import time
x=1000
def task():
time.sleep(3)
global x
x=0
print('兒子死啦',x)
#在以前最好只有函數或變量的定義,沒有具體的執行(print等)
if __name__ == '__main__':
p=Process(target=task)
p.start()
time.sleep(5)
print(x)
#在子進程中對變量x的修改不影響父進程中x的值
if __name__ == '__main__':
p=Process(target=task)
p.start()
time.sleep(5)
print(x)
#在子進程中對變量x的修改不影響父進程中x的值
4、父進程等待子進程結束 p1.join()
#(等待p1 卡住)等兒子死了,wait回收兒子的pid等遺留下的東西
#瞭解 連續start再連續join 和 連續start,join。。。。
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p2.start()
p3.start()
p3.join() #3s
p1.join()
p2.join()
print('主',(time.time() - start_time)) #3.01637601852417
#瞭解 連續start再連續join 和 連續start,join。。。。
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p2.start()
p3.start()
p3.join() #3s
p1.join()
p2.join()
print('主',(time.time() - start_time)) #3.01637601852417
#用循環
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p_l=[]
for i in range(1,4):
p=Process(target=task,args=(i,))
p_l.append(p)
p.start()
for p in p_l:
p.join()
print('主',(time.time() - start_time)) #3.0141923427581787
from multiprocessing import Process
import time
x=1000
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__':
start_time=time.time()
p_l=[]
for i in range(1,4):
p=Process(target=task,args=(i,))
p_l.append(p)
p.start()
for p in p_l:
p.join()
print('主',(time.time() - start_time)) #3.0141923427581787
5、進程對象的其餘屬性
from multiprocessing import Process
import time
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__': # 在windows系統之上,開啓子進程的操做必定要放到這下面
start_time=time.time()
p1=Process(target=task,args=(1,),name='任務1')
p1 daemon=True #再obj發出建立前,將obj變成守護進程,主進程執行完畢後子進程跟着結束
p1.start() #向操做系統發建立子進程請求,父進程無需等待
print(p1.pid)
print(p1.name) #如前面不定義name,默認process-1 etc
p1.terminate() #向操做系統發請求,父進程無需等待
p1.join() #等待該子進程結束(卡住吧),父進程須要等待一點時間
print(p1.is_alive())
print('主') #這裏的效果是主進程等兒子死了,再結束
from multiprocessing import Process
import time
def task(n):
print('%s is runing' %n)
time.sleep(n)
if __name__ == '__main__': # 在windows系統之上,開啓子進程的操做必定要放到這下面
start_time=time.time()
p1=Process(target=task,args=(1,),name='任務1')
p1 daemon=True #再obj發出建立前,將obj變成守護進程,主進程執行完畢後子進程跟着結束
p1.start() #向操做系統發建立子進程請求,父進程無需等待
print(p1.pid)
print(p1.name) #如前面不定義name,默認process-1 etc
p1.terminate() #向操做系統發請求,父進程無需等待
p1.join() #等待該子進程結束(卡住吧),父進程須要等待一點時間
print(p1.is_alive())
print('主') #這裏的效果是主進程等兒子死了,再結束
from multiprocessing import Process
import time,os
def task():
print('self:%s parent:%s' %(os.getpid(),os.getppid()))
time.sleep(3)
if __name__ == '__main__':
p1=Process(target=task,)
p1.start()
print(p1.pid)
print('主',os.getpid())
import time,os
def task():
print('self:%s parent:%s' %(os.getpid(),os.getppid()))
time.sleep(3)
if __name__ == '__main__':
p1=Process(target=task,)
p1.start()
print(p1.pid)
print('主',os.getpid())
6、殭屍進程與孤兒進程
在unix系統中init是全部進程的爹;建立進程用fork,回收進程(結束進程的殘留信息?)用waitpid
殭屍進程(有害:佔用pid):子代先於父代終結,其部分信息(pid等)沒有從系統中刪除,須要父代回收。join中含有回收子代信息的功能。
孤兒進程(無害):父代先於子代終結,子代終結後的部分信息由init代收。
在unix系統中init是全部進程的爹;建立進程用fork,回收進程(結束進程的殘留信息?)用waitpid
殭屍進程(有害:佔用pid):子代先於父代終結,其部分信息(pid等)沒有從系統中刪除,須要父代回收。join中含有回收子代信息的功能。
孤兒進程(無害):父代先於子代終結,子代終結後的部分信息由init代收。
from multiprocessing import Process
import time,os
def task(n):
print('%s is running' %n)
time.sleep(n)
if __name__ == '__main__':
1=Process(target=task,args=(1,))
p1.start()
p1.join() # join中含有回收子代信息的功能(wait)
print('======主',os.getpid())
import time,os
def task(n):
print('%s is running' %n)
time.sleep(n)
if __name__ == '__main__':
1=Process(target=task,args=(1,))
p1.start()
p1.join() # join中含有回收子代信息的功能(wait)
print('======主',os.getpid())
7、守護進程
父進程 代碼運行完(主線程運行代碼),守護進程就結束
from multiprocessing import Process
import time
from multiprocessing import Process
import time
def task(name):
print('%s is running' % name)
time.sleep(3)
print('%s is running' % name)
time.sleep(3)
if __name__ == '__main__':
obj = Process(target=task, args=('egon',))
obj.daemon=True #將obj變成守護進程,主進程執行完畢後子進程跟着結束
obj.start() # 發送信號給操做系統
print('主')
obj = Process(target=task, args=('egon',))
obj.daemon=True #將obj變成守護進程,主進程執行完畢後子進程跟着結束
obj.start() # 發送信號給操做系統
print('主')
8、互斥鎖
強調:必須是lock.acquire()一次,而後 lock.release()釋放一次,才能繼續lock.acquire(),不能連續的lock.acquire()。否者程序停在原地。
搶同一把鎖:生成鎖對象 必須放在if __name__=='__main__': 下面
互斥鎖vs join:
大前提:兩者的原理都是同樣,都是將併發變成串行,從而保證有序(在多個程序共享一個資源時,爲保證有序不亂,需將併發變成串行)
場景: 修改公共數據,若是併發會發出數據錯亂,這時就必須串行執行,就要用到互斥鎖
區別一:join是按照人爲指定的順序執行,而互斥鎖是因此進程平等地競爭,誰先搶到誰執行
區別二:互斥鎖可讓一部分代碼串行,而join只能將代碼總體串行(詳見搶票系統)
理解:首先join確定是一個子進程對象,互斥鎖能夠加在子進程對象代碼任意部位(要釋放額)
join人爲安排子進程執行順序,互斥鎖是公平競爭。
from multiprocessing import Process,Lock
import time,random
強調:必須是lock.acquire()一次,而後 lock.release()釋放一次,才能繼續lock.acquire(),不能連續的lock.acquire()。否者程序停在原地。
搶同一把鎖:生成鎖對象 必須放在if __name__=='__main__': 下面
互斥鎖vs join:
大前提:兩者的原理都是同樣,都是將併發變成串行,從而保證有序(在多個程序共享一個資源時,爲保證有序不亂,需將併發變成串行)
場景: 修改公共數據,若是併發會發出數據錯亂,這時就必須串行執行,就要用到互斥鎖
區別一:join是按照人爲指定的順序執行,而互斥鎖是因此進程平等地競爭,誰先搶到誰執行
區別二:互斥鎖可讓一部分代碼串行,而join只能將代碼總體串行(詳見搶票系統)
理解:首先join確定是一個子進程對象,互斥鎖能夠加在子進程對象代碼任意部位(要釋放額)
join人爲安排子進程執行順序,互斥鎖是公平競爭。
from multiprocessing import Process,Lock
import time,random
mutex=Lock() #這裏每一個子進程的都會申請一把鎖
print(id(mutex))
print(id(mutex))
def task1(lock):
lock.acquire()
# print('task1:名字是egon')
# time.sleep(random.randint(1,3))
# print('task1:性別是male')
time.sleep(random.randint(1,3)) #with mutex: time.sleep(random.randint(1,3))
# print('task1:年齡是18')
lock.release()
lock.acquire()
# print('task1:名字是egon')
# time.sleep(random.randint(1,3))
# print('task1:性別是male')
time.sleep(random.randint(1,3)) #with mutex: time.sleep(random.randint(1,3))
# print('task1:年齡是18')
lock.release()
def task2(lock):
lock.acquire()
print('task2:名字是alex')
time.sleep(random.randint(1,3))
print('task2:性別是male')
time.sleep(random.randint(1,3))
print('task2:年齡是78')
lock.release()
lock.acquire()
print('task2:名字是alex')
time.sleep(random.randint(1,3))
print('task2:性別是male')
time.sleep(random.randint(1,3))
print('task2:年齡是78')
lock.release()
def task3(lock):
lock.acquire()
print('task3:名字是lxx')
time.sleep(random.randint(1,3))
print('task3:性別是female')
time.sleep(random.randint(1,3))
print('task3:年齡是30')
lock.release()
lock.acquire()
print('task3:名字是lxx')
time.sleep(random.randint(1,3))
print('task3:性別是female')
time.sleep(random.randint(1,3))
print('task3:年齡是30')
lock.release()
if __name__ == '__main__':
p1=Process(target=task1,args=(mutex,))
p2=Process(target=task2,args=(mutex,))
p3=Process(target=task3,args=(mutex,))
p1=Process(target=task1,args=(mutex,))
p2=Process(target=task2,args=(mutex,))
p3=Process(target=task3,args=(mutex,))
p1.start()
p2.start()
p3.start()
p2.start()
p3.start()
last、搶票系統
import json
import time
import random
import os
from multiprocessing import Process,Lock
import json
import time
import random
import os
from multiprocessing import Process,Lock
mutex=Lock() #每一個子進程都會生成 一把鎖對象,沒用到。能夠優化放在下面 __name__裏面
def search():
time.sleep(random.randint(1,3))
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
print('%s 剩餘票數:%s' %(os.getpid(),dic['count']))
time.sleep(random.randint(1,3))
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
print('%s 剩餘票數:%s' %(os.getpid(),dic['count']))
def get():
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
if dic['count'] > 0:
dic['count']-=1
time.sleep(random.randint(1,3))
with open('db.json','w',encoding='utf-8') as f:
json.dump(dic,f)
print('%s 購票成功' %os.getpid())
with open('db.json','r',encoding='utf-8') as f:
dic=json.load(f)
if dic['count'] > 0:
dic['count']-=1
time.sleep(random.randint(1,3))
with open('db.json','w',encoding='utf-8') as f:
json.dump(dic,f)
print('%s 購票成功' %os.getpid())
def task(lock):
search()
lock.acquire()
get()
lock.release()
search()
lock.acquire()
get()
lock.release()
if __name__ == '__main__':
for i in range(10):
p=Process(target=task,args=(mutex,)) #這裏子進程用的都是主進程這一把鎖 id p.start()
for i in range(10):
p=Process(target=task,args=(mutex,)) #這裏子進程用的都是主進程這一把鎖 id p.start()