"""一台計算機上面執行著很多程序,那麼計算機是如何區分並管理這些程序服務端的呢?
計算機會給每乙個執行的程序分配乙個pid號
如何檢視
windows電腦
進入cmd輸入tasklist即可檢視
tasklist |findstr pid檢視具體的程序
mac電腦
進入終端之後輸入ps aux
ps aux|grep pid檢視具體的程序
"""from
multiprocessing
import
process, current_process
current_process().pid
# 檢視當前程序的程序號
import
osos.getpid() # 檢視當前程序程序號
os.getppid() # 檢視當前程序的父程序程序號
p.terminate() # 殺死當前程序
# 是告訴作業系統幫你去殺死當前程序 但是需要一定的時間 而**的執行速度極快
time.sleep(0.1)
print(p.is_alive())
# 判斷當前程序是否存活
# 殭屍程序"""死了但是沒有死透
當你開設了子程序之後 該程序死後不會立刻釋放占用的程序號
因為我要讓父程序能夠檢視到它開設的子程序的一些基本資訊 占用的pid號 執行時間。。。
所有的程序都會步入殭屍程序
父程序不死並且在無限制的建立子程序並且子程序也不結束
**子程序占用的pid號
父程序等待子程序執行結束
父程序呼叫join方法
"""
# 孤兒程序
"""子程序存活,父程序意外死亡
作業系統會開設乙個「兒童福利院」專門管理孤兒程序**相關資源
"""
from多個程序操作同乙份資料的時候,會出現資料錯亂的問題multiprocessing
import
process
import
time
deftask(name):
print('%s總管正在活著'
%name)
time.sleep(3)
print('%s總管正在死亡'
%name)
if__name__ == '__main__':
p = process(target=task,args=('egon',))
# p = process(target=task,kwargs=)
p.daemon = true
# 將程序p設定成守護程序 這一句一定要放在start方法上面才有效否則會直接報錯
p.start()
print('皇帝jason壽終正寢')
針對上述問題,解決方式就是加鎖處理:
將併發變成序列,犧牲效率但是保證了資料的安全
例——買票(搶票)
frommultiprocessing
import
process, lock
import
json
import
time
import
random
# 查票
defsearch(i):
# 檔案操作讀取票數
with
open('data','r',encoding='utf8') as
f:dic = json.load(f)
print('使用者%s查詢餘票:%s'
%(i, dic.get('ticket_num')))
# 字典取值不要用的形式 推薦使用get 你寫的**打死都不能報錯!!!
# 買票 1.先查 2.再買
defbuy(i):
# 先查票
with
open('data','r',encoding='utf8') as
f:dic = json.load(f)
# 模擬網路延遲
time.sleep(random.randint(1,3))
# 判斷當前是否有票
ifdic.get('ticket_num') >
0:# 修改資料庫 買票
dic['ticket_num'] -= 1
# 寫入資料庫
with
open('data','w',encoding='utf8') as
f:json.dump(dic,f)
print('使用者%s買票成功'%i)
else:
print('使用者%s買票失敗'%i)
# 整合上面兩個函式
defrun(i, mutex):
search(i)
# 給買票環節加鎖處理
# 搶鎖
mutex.acquire()
buy(i)
# 釋放鎖
mutex.release()
if__name__ == '__main__':
# 在主程序中生成一把鎖 讓所有的子程序搶 誰先搶到誰先買票
mutex = lock()
fori
inrange(1,11):
p = process(target=run, args=(i, mutex))
p.start()
"""擴充套件 行鎖 表鎖
注意:
1.鎖不要輕易的使用,容易造成死鎖現象(我們寫**一般不會用到,都是內部封裝好的)
2.鎖只在處理資料的部分加來保證資料安全(只在爭搶資料的環節加鎖處理即可)
"""
佇列queue模組
"""管道:subprocess
stdin stdout stderr
佇列:管道+鎖
佇列:先進先出
堆疊:先進後出
"""from
multiprocessing
import
queue
# 建立乙個佇列
q = queue(5) # 括號內可以傳數字 標示生成的佇列最大可以同時存放的資料量
# 往佇列中存資料
q.put(111)
q.put(222)
q.put(333)
# print(q.full()) # 判斷當前佇列是否滿了
# print(q.empty()) # 判斷當前佇列是否空了
q.put(444)
q.put(555)
# print(q.full()) # 判斷當前佇列是否滿了
# q.put(666) # 當佇列資料放滿了之後 如果還有資料要放程式會阻塞 直到有位置讓出來 不會報錯
"""
訪問資料 存是為了更好的取
千方百計的存、簡單快捷的取
"""
# 去佇列中取資料
v1 = q.get()
v2 = q.get()
v3 = q.get()
v4 = q.get()
v5 = q.get()
# print(q.empty())
# v6 = q.get_nowait() # 沒有資料直接報錯queue.empty
# v6 = q.get(timeout=3) # 沒有資料之後原地等待三秒之後再報錯 queue.empty
try:
v6 = q.get(timeout=3)
print(v6)
except
exception
ase:
print('一滴都沒有了!')
# # v6 = q.get() # 佇列中如果已經沒有資料的話 get方法會原地阻塞
# print(v1, v2, v3, v4, v5, v6)
"""
q.full()
q.empty()
q.get_nowait()
在多程序的情況下是不精確
當佇列資料放滿了之後 如果還有資料要放程式會阻塞 直到有位置讓出來 不會報錯
佇列中如果已經沒有資料的話 get方法會原地阻塞
q.get_nowait() / q.get(timeout=3) 會報錯(可用異常捕捉方法)
"""
frommultiprocessing
import
queue, process
"""
研究思路
1.主程序跟子程序借助於佇列通訊
2.子程序跟子程序借助於佇列通訊
"""def
producer(q):
q.put('我是23號技師 很高興為您服務')
defconsumer(q):
print(q.get())
if__name__ == '__main__':
q = queue()
p = process(target=producer,args=(q,))
p1 = process(target=consumer,args=(q,))
p.start()
p1.start()
併發程式設計(2)
作用 private volatile int a 0 強制執行緒到共享記憶體中讀取資料,而不是從執行緒工作中讀取,從而使變數在多個執行緒間可見。volatile無法保證原子性,volatile是輕量級的同步,效能比synchronized強很多,但是只是保證了效能的可見性,並不能替代synchro...
併發程式設計2
2.自旋鎖 spinlock 3.訊號量 2.synchronizer.cpp中對應的slow enter 3.鎖膨脹 inflate也在synchronizer.cpp中 因此synchronized不是自旋鎖 2.什麼時候變成重量級鎖,是因為鎖膨脹,是可逆的,當乙個執行緒持有鎖,當另乙個也來獲取...
併發程式設計2
守護程序 守護程序也是乙個程序,可以守護著另乙個程序 乙個程序a設定為b的守護程序,當b結束時a會立刻結束自己不管任務是否執行完畢 將程序的daemon屬性設定為true時這個程序變成了守護程序,設定daemon屬性時必須在開始程序之前 程序安全 使用lock來例項化產生一把鎖,但是要保證每乙個程序...