欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python multiprocessing多進(jìn)程變量共享與加鎖的實(shí)現(xiàn)

 更新時(shí)間:2019年10月02日 10:00:11   作者:京醬玫瑰  
這篇文章主要介紹了python multiprocessing多進(jìn)程變量共享與加鎖的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

python多進(jìn)程和多線程是大家會(huì)重點(diǎn)了解的部分,因?yàn)楹芏喙ぷ魅绻](méi)有前后相互依賴關(guān)系的話其實(shí)順序并不是非常的重要,采用順序執(zhí)行的話就必定會(huì)造成無(wú)謂的等待,任憑cpu和內(nèi)存白白浪費(fèi),這是我們不想看到的。

為了解決這個(gè)問(wèn)題,我們就可以采用多線程或者多進(jìn)程的方式,(多線程我們之后再講),而這兩者之間是有本質(zhì)區(qū)別的。就內(nèi)存而言,已知進(jìn)程是在執(zhí)行過(guò)程中有獨(dú)立的內(nèi)存單元的,而多個(gè)線程是共享內(nèi)存的,這是多進(jìn)程和多線程的一大區(qū)別。

利用Value在不同進(jìn)程中同步變量

在多進(jìn)程中,由于進(jìn)程之間內(nèi)存相互是隔離的,所以無(wú)法在多個(gè)進(jìn)程中用直接讀取的方式共享變量,這時(shí)候就可以用multiprocessing庫(kù)中的 Value在各自隔離的進(jìn)程中共享變量。

下面是一個(gè)多進(jìn)程的例子:

假設(shè)有一個(gè)counter用來(lái)記錄程序經(jīng)過(guò)的總循環(huán)次數(shù),每調(diào)用一次count函數(shù)之后counter就會(huì)增加20,在主程序中用循環(huán)開(kāi)10個(gè)進(jìn)程分別調(diào)用count函數(shù),那么理想狀態(tài)下,在十個(gè)進(jìn)程中共享的counter值到程序結(jié)束后應(yīng)該是200。

from multiprocessing import Process, Value
import time

def count(v):
  for i in range(20):
    time.sleep(0.01)
    v.value += 1

def main():
  value = Value('i',0)
  processes = [Process(target=count, args=(value,)) for i in range(10)]

  for p in processes:
    p.start()
  for p in processes:
    p.join()

  print(value.value)

if __name__ == '__main__':

  for i in range(10):
    main()

運(yùn)行這個(gè)例子,會(huì)得到怎樣的結(jié)果呢?

188
180
168
186
183
179
186
181
166
186

我在主程序里運(yùn)行了十次這個(gè)程序,而最后的結(jié)果是160-180之間,總之,沒(méi)有一次到200。這是什么原因呢?

相信很多人都已經(jīng)明白了問(wèn)題所在,那就是因?yàn)樵趍ultiprocessing庫(kù)中的Value是細(xì)粒度的,Value中有一個(gè)ctypes類型的對(duì)象,擁有一個(gè)value屬性來(lái)表征內(nèi)存中實(shí)際的對(duì)象。Value可以保證同時(shí)只有一個(gè)單獨(dú)的線程或進(jìn)程在讀或者寫(xiě)value值。這么看起來(lái)沒(méi)有什么問(wèn)題。

然而在第一個(gè)進(jìn)程加載value值的時(shí)候,程序卻不能阻止第二個(gè)進(jìn)程加載舊的值。兩個(gè)進(jìn)程都會(huì)把value拷貝到自己的私有內(nèi)存然后進(jìn)行處理,并寫(xiě)回到共享值里。

那么這么會(huì)出現(xiàn)什么問(wèn)題呢?

最后的共享值只接收到了一次值的增加,而非兩次。

利用Lock在不同進(jìn)程共享變量時(shí)加鎖

上面的問(wèn)題其實(shí)可以用一個(gè)非常簡(jiǎn)單的方法解決,我們只需要調(diào)用multiprocessing庫(kù)中的Lock (鎖)就可以保證一次只能有一個(gè)進(jìn)程訪問(wèn)這個(gè)共享變量。修改后的代碼如下:

from multiprocessing import Process, Value, Lock
from time import sleep

def count(x,lock):
  for i in range(20):
    sleep(0.01)
    with lock:
      x.value += 1


def main():
  counter = Value('i',0)
  lock = Lock()
  processes = [Process(target=count,args=(counter,lock)) for i in range(10)]
  for p in processes:
    p.start()
  for p in processes:
    p.join()

  print(counter.value)

if __name__ == '__main__':
  for i in range(10):
    main()

這樣一來(lái),輸出的結(jié)果就會(huì)恒定為200了。

一些補(bǔ)充

1. 調(diào)用get_lock() 函數(shù)

其實(shí)Value這個(gè)包里已經(jīng)包含了鎖的概念,如果調(diào)用get_lock() 函數(shù)就可以自動(dòng)給共享變量加鎖。這樣其實(shí)是比較推薦的方式,因?yàn)檫@樣就不需要同時(shí)調(diào)用兩個(gè)包。修改如下:

from multiprocessing import Process, Value
from time import sleep

def count(x):
  for i in range(20):
    global counter # 聲明全局變量
    sleep(0.01)
    with counter.get_lock(): # 直接調(diào)用get_lock()函數(shù)獲取鎖
      x.value += 1

def main():
  processes = [Process(target=count, args=(counter,)) for i in range(10)]
  for p in processes:
    p.start()
  for p in processes:
    p.join()

  print(counter.value)

if __name__ == '__main__':
  counter = Value('i', 0) # 需要把全局變量移到主程序
  main()

上面的程序更加明確,且最終結(jié)果也是200。

2. 使用 multiprocessing.RawValue

整個(gè)multiprocessing包里剛剛調(diào)用的Value和Lock還可以統(tǒng)一被 multiprocessing.RawValue取代。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python文件操作之目錄遍歷實(shí)例分析

    python文件操作之目錄遍歷實(shí)例分析

    這篇文章主要介紹了python文件操作之目錄遍歷的方法,以實(shí)例形式較為詳細(xì)的分析了目錄遍歷所需要用到的相關(guān)函數(shù)與使用技巧,需要的朋友可以參考下
    2015-05-05
  • python 實(shí)現(xiàn)定時(shí)任務(wù)的四種方式

    python 實(shí)現(xiàn)定時(shí)任務(wù)的四種方式

    這篇文章主要介紹了python 實(shí)現(xiàn)定時(shí)任務(wù)的四種方式,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-04-04
  • python修改全局變量可以不加global嗎?

    python修改全局變量可以不加global嗎?

    這篇文章主要探討的是python修改全局變量可不可以不加global,我們?cè)诰植孔饔糜騼?nèi)使用全局變量,需要使用global關(guān)鍵字進(jìn)行聲明,不然便不可用,但下面小編就和大家分享可以修改的數(shù)據(jù)類型在函數(shù)內(nèi)部做修改操作是不需要聲明global的商務(wù)情況,需要的朋友可以參考下
    2022-02-02
  • Python使用ntplib庫(kù)同步校準(zhǔn)當(dāng)?shù)貢r(shí)間的方法

    Python使用ntplib庫(kù)同步校準(zhǔn)當(dāng)?shù)貢r(shí)間的方法

    NTP網(wǎng)絡(luò)時(shí)間協(xié)議其實(shí)大家平時(shí)或多或少都能接觸到,包括Windows在內(nèi)的操作系統(tǒng)中的很多Internet時(shí)間同步功能都是在NTP的基礎(chǔ)上來(lái)做,這里我們來(lái)看一下Python使用ntplib庫(kù)同步校準(zhǔn)當(dāng)?shù)貢r(shí)間的方法
    2016-07-07
  • 最新評(píng)論