黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

113 Python程序中的進(jìn)程操作-進(jìn)程同步

系統(tǒng) 1891 0

目錄

  • 一、進(jìn)程同步
  • 二、為什么需要進(jìn)程同步
  • 三、Python中實(shí)現(xiàn)進(jìn)程同步
  • 四、多進(jìn)程模擬同時(shí)搶票
    • 4.1 通過鎖控制進(jìn)程資源訪問
  • 總結(jié)

盡管并發(fā)編程讓我們能更加充分的利用IO資源,但是也給我們帶來了新的問題: 當(dāng)多個(gè)進(jìn)程使用同一份數(shù)據(jù)資源的時(shí)候,就會(huì)引發(fā)數(shù)據(jù)安全或順序混亂問題。

一、進(jìn)程同步

多個(gè)進(jìn)程同時(shí)執(zhí)行,為了相互制約各進(jìn)程對(duì)資源的訪問,使得各個(gè)進(jìn)程的執(zhí)行相互同步。

在我的理解里,進(jìn)程同步也算是進(jìn)程間通訊(ipc)的一種手段。

二、為什么需要進(jìn)程同步

多進(jìn)程會(huì)引發(fā)搶占資源的問題,為了解決這個(gè)問題就需要各進(jìn)程之間相互同步,控制進(jìn)程對(duì)關(guān)鍵資源的訪問。

在C語言中實(shí)現(xiàn)進(jìn)程同步的方式有很多,比如:信號(hào)量,鎖機(jī)制等。

例子: 演示多進(jìn)程資源搶占問題

          
            import os
import time
import random
from multiprocessing import Process

def work(n):
    print('%s: %s is running' %(n,os.getpid()))
    time.sleep(random.random())
    print('%s:%s is done' %(n,os.getpid()))

if __name__ == '__main__':
    for i in range(3):
        p=Process(target=work,args=(i,))
        p.start()
          
        

三、Python中實(shí)現(xiàn)進(jìn)程同步

  1. 首先 from multiprocessing import Lock
  2. 在主進(jìn)程中,實(shí)例化得到鎖, lock = Lock() ,并傳給子進(jìn)程
  3. 在子進(jìn)程中通過上鎖和解鎖實(shí)現(xiàn)對(duì)多進(jìn)程對(duì)資源的控制。 lock.acquire() 上鎖, lock.release() 解鎖

演示:通過Python鎖機(jī)制控制資源的訪問

          
            def work(lock,n):
    print(f"等待開鎖 進(jìn)程{n}")
    # 上鎖
    lock.acquire()     # 當(dāng)上鎖之后別的進(jìn)程無法訪問,會(huì)阻塞住
    print(f'進(jìn)程{n} pid: %s is running' % ( os.getpid()))
    time.sleep(random.random())
    print(f'進(jìn)程{n} pid: %s is done' % (os.getpid()))
    # 開鎖
    lock.release()

if __name__ == '__main__':
    lock=Lock() # 實(shí)例化得到鎖
    for i in range(3):
        p=Process(target=work,args=(lock,i))
        p.start()
          
        

等待開鎖 進(jìn)程1
進(jìn)程1 pid: 8696 is running
等待開鎖 進(jìn)程0
等待開鎖 進(jìn)程2
進(jìn)程1 pid: 8696 is done
進(jìn)程0 pid: 14264 is running
進(jìn)程0 pid: 14264 is done
進(jìn)程2 pid: 22724 is running
進(jìn)程2 pid: 22724 is done

根據(jù)結(jié)果可以發(fā)現(xiàn),在上鎖之前的代碼。多進(jìn)程是并發(fā)訪問的,但上鎖之后,直到解鎖后才能有第二個(gè)人訪問。以此類推。 就好像上廁所排隊(duì)一樣,進(jìn)去一個(gè)人關(guān)上門鎖上,第二個(gè)人等著。

但是看完你會(huì)有個(gè)疑問,那被鎖上的代碼,每個(gè)進(jìn)程在訪問的時(shí)候不就是串行的依次在訪問嘛。

確實(shí),鎖機(jī)制 保證了數(shù)據(jù)的安全,但犧牲掉效率.

四、多進(jìn)程模擬同時(shí)搶票

          
            # 文件db的內(nèi)容為:{"count":1}
# 注意一定要用雙引號(hào),不然json無法識(shí)別
# 并發(fā)運(yùn)行,效率高,但競爭寫同一文件,數(shù)據(jù)寫入錯(cuò)亂
from multiprocessing import Process,Lock
import time,json,random
def search():
    dic=json.load(open('db'))
    print('剩余票數(shù)%s' %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'))
        print('購票成功')

def task():
    search()
    get()

if __name__ == '__main__':
    for i in range(100):  # 模擬并發(fā)100個(gè)客戶端搶票
        p=Process(target=task)
        p.start()
          
        

上述代碼,你會(huì)發(fā)現(xiàn)多個(gè)進(jìn)程在同時(shí)搶票,相互搶占文件資源,每個(gè)進(jìn)程都把文件讀入到內(nèi)存中進(jìn)行搶票。實(shí)際上,資源只能被一個(gè)人占有,這就會(huì)引發(fā)問題

4.1 通過鎖控制進(jìn)程資源訪問

          
            def search():
    time.sleep(1)
    with open("db","w",encoding="utf8") as f:
        data = json.load(f)
        print(f'還剩{data["count"]}')

def get():
    with open('db','rt',encoding='utf-8') as f:
        res = json.load(f)
    time.sleep(1)  # 模擬網(wǎng)絡(luò)io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db', 'w', encoding='utf-8') as f:
            json.dump(res, f)
            print(f'進(jìn)程{os.getpid()} 搶票成功')
        time.sleep(1.5)  # 模擬網(wǎng)絡(luò)io
    else:
        print('票已經(jīng)售空啦!!!!!!!!!!!')

def task(lock):
    print(f"進(jìn)程:{os.getpid()}  正在搶票中。。。")

    # 上鎖     每個(gè)進(jìn)程都會(huì)訪問一遍,所以加鎖就等于上鎖到解鎖這段代碼是串行的
    lock.acquire()  # 當(dāng)上鎖之后別的進(jìn)程無法訪問,會(huì)阻塞住
    get()
    # 開鎖
    lock.release()

if __name__ == '__main__':
    # 創(chuàng)建鎖
    lock = Lock()

    pro_list = []
    # 創(chuàng)建進(jìn)程
    for i in range(10):
        p = Process(target=task, args=(lock,))
        p.start()
        pro_list.append(p)
    # 回收進(jìn)程
    for i in range(10):
        pro_list[i].join()
          
        

總結(jié)

進(jìn)程同步理論上應(yīng)該是進(jìn)程間通訊中的一部分,是一個(gè)大話題,每個(gè)語言也都有實(shí)現(xiàn)進(jìn)程同步的需求。需要將各個(gè)進(jìn)程對(duì)資源的訪問加以限制。在各個(gè)語言中也都有限制。這里目前只介紹了這一種進(jìn)程同步的方法。

鎖機(jī)制 是把鎖住的代碼變成了串行,保證了數(shù)據(jù)的安全,但犧牲掉效率.


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論