"""
問題:當(dāng)多個進(jìn)程使用同一份數(shù)據(jù)資源的時候,就會引發(fā)數(shù)據(jù)安全或順序混亂的問題
"""
'''
進(jìn)程同步
'''
#多進(jìn)程搶占輸出資源
import os
import time
import random
from multiprocessing import Process
def work(n):
print(f'{n}: {os.getpid()} is running')
# time.sleep(random.random())
time.sleep(2)
print(f"{n}: {os.getpid()} is done")
if __name__ == '__main__':
for i in range(3):
p = Process(target= work, args=(i, ))
p.start()
#使用鎖維護(hù)執(zhí)行順序
#由并發(fā)變成了串行,犧牲了運(yùn)行效率,但避免了競爭
import os,time,random
from multiprocessing import Process,Lock
def work(lock, n):
lock.acquire()
print(f'{n}: {os.getpid()} is running')
time.sleep(random.randint(1, 3))
print(f'{n}: {os.getpid()} is done')
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(3):
p = Process(target=work, args=(lock, i))
p.start()
'''加鎖可以實(shí)現(xiàn)順序的執(zhí)行,但是程序又重新變成串行了,
浪費(fèi)時間但是保證了數(shù)據(jù)安全
'''
#文件db的內(nèi)容為:{"count": 1}
#注意一定要用雙引號,不然json無法識別
#并發(fā)運(yùn)行,效率高,但競爭寫同一文件,數(shù)據(jù)寫入錯亂
from multiprocessing import Process,Lock
import time, json, random
def search():#查詢剩余票數(shù)
dic = json.load(open('db')) #從文件中把數(shù)據(jù)讀出來
# 下面兩句和上面一句的功能一樣
# data = open('db')
# dic = json.load(data)
print(f'剩余票數(shù){dic["count"]}')#打印
def get():#買票
dic = json.load(open('db')) #打開文件
time.sleep(0.1) #模擬讀數(shù)據(jù)的網(wǎng)絡(luò)延遲
if dic['count'] > 0:
dic['count'] -= 1
time.sleep(0.2) #模擬寫數(shù)據(jù)的網(wǎng)絡(luò)延遲
json.dump(dic, open('db', 'w'))
# 下面兩句和上面一句會得到相同的效果
# data = open('db', 'w')
# json.dump(dic, data)
print('購票成功')
def task():
search()
get()
if __name__ == '__main__':
for i in range(100): # 模擬并發(fā)100個客戶端搶票
p = Process(target=task)
p.start()
#用鎖來保證數(shù)據(jù)安全
from multiprocessing import Process,Lock
import time, json, random
def search():#查詢剩余票數(shù)
dic = json.load(open('db')) #從文件中把數(shù)據(jù)讀出來
# 下面兩句和上面一句的功能一樣
# data = open('db')
# dic = json.load(data)
print(f'剩余票數(shù){dic["count"]}')#打印
def get():#買票
dic = json.load(open('db')) #打開文件
time.sleep(random.random()) #模擬讀數(shù)據(jù)的網(wǎng)絡(luò)延遲
if dic['count'] > 0:
dic['count'] -= 1
time.sleep(random.random()) #模擬寫數(shù)據(jù)的網(wǎng)絡(luò)延遲
json.dump(dic, open('db', 'w'))
# 下面兩句和上面一句會得到相同的效果
# data = open('db', 'w')
# json.dump(dic, data)
print('購票成功')
def task(lock):
search()
lock.acquire()
get()
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(30): # 模擬并發(fā)30個客戶端搶票
p = Process(target=task, args=(lock, ))
p.start()
"""
加鎖可以保證多個進(jìn)程修改同一塊數(shù)據(jù)時,同一時間只
能有一個任務(wù)可以修改即串行的修改,速度慢了,但是數(shù)
據(jù)變安全了。
文件共享數(shù)據(jù)實(shí)現(xiàn)進(jìn)程間通信,問題有:
1.效率低(共享數(shù)據(jù)基于文件,而文件是在硬盤上的數(shù)據(jù))
2.需要自己加鎖處理
我們需要:
1.效率高,(多個進(jìn)程共享一塊內(nèi)存的數(shù)據(jù))
2.幫我們處理好鎖問題,這就是multiprocessing模塊提供
的基于消息的IPC通信機(jī)制:隊(duì)列和管道
注意:
隊(duì)列和管道都是將數(shù)據(jù)存放于內(nèi)存中,隊(duì)列又是基于(管道+鎖)
實(shí)現(xiàn)的,可以讓我們從復(fù)雜的鎖問題中解脫出來,我們應(yīng)該盡量
避免使用共享數(shù)據(jù),盡可能使用消息傳遞和隊(duì)列,避免處理復(fù)
雜的同步和鎖問題,而且在進(jìn)程數(shù)目增多時,往往可以獲得更好的可獲展性。
"""
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
