1. 程式人生 > >並發通信Manage,隊列, 互斥鎖

並發通信Manage,隊列, 互斥鎖

自加 target 才會 解決方案 range 子進程 color 並且 資源競爭

Manage

進程間的通信是被限制的

from multiprocessing import Process

a = 1

def func():
    global a    # 聲明全局變量
    a = 2    # 修改全局變量

func()
print(a)

p = Process(target=func)
p.start()
p.join()
print(a)

兩個結果,第一個是2,第二個是1-----> 進程內存空間是獨立的

解決方案:開辟一個新的進程空間,通過代理器和管理器進行通信

  1, 管理器負責與公共進程通信

  2, 代理負責操作共享空間

技術分享圖片

from multiprocessing import Process, Manage(管理器)

mgr = Manage() # 先開啟一個子進程(守護進程),並且返回一個用來通信的管理器

shared_list = mgr.list()    # 通過Manage管理器開啟一個公共l列表空間(代理)

def func(lis):
    lis.appent(hello)

p = Process(target=func, args=(shared_list, ))
p.start(0
p.join()

print(shared_list)


--> [hello
]

  這裏需要知道,可以開啟的代理空間有以下幾個:

      mgr.list() 列表

      mgr.dict() 字典

      mgr.Queue() 隊列

  隊列 先入先出

隊列操作:

  入列:put()

  出列:get()

  測試空:empty() 近似值

  測試滿:funll() 近似值

  隊列長度:qsize() 近似值

  任務結束: task_done()

  等待完成:join()

   需要了解的是,隊列中存在一個計數器的概念,當put的時候,計數器會加1,當task_done時,計數器減1

   可以用join進行測試,當計數器不是0,隊列會阻塞,只有當計數器為0時,才會解阻塞

線程間的通信不存在限制,但是會存在資源競爭的問題,即同時執行的線程,公用共享資源的時候,會搶占資源,導致數據亂序

所以需要互斥鎖來鎖定某些操作

import threading from Thread, Lock

lock = Lock() # 實例化一個鎖

      with lock:
            xxxxxxxx
‘‘‘
或者:
lock.acquire() # 上鎖
xxxxxxxx
lock.release() # 解鎖

xxxxxx能少則少
鎖不能加太多,會大大下降性能
‘‘‘

 1 from threading import Thread, Lock
 2 
 3 lock = Lock()   # 實例化一個鎖的實例
 4 a = 0
 5 
 6 def incr(n):  # 自加
 7     global a
 8     for i in range(n):
 9         with lock:
10             a += 1
11 
12 def decr(n):  # 自減
13     global a
14     for i in range(n):
15         with lock:
16             a -= 1
17 
18 t = Thread(target=incr, args=(1000000, ))
19 t2 = Thread(target=decr, args=(1000000, ))
20 t.start()
21 t2.start()
22 t.join()
23 t2.join()
24 print(a)
25 
26 --> 0



如果不加鎖,線程之間會競爭資源,得到的結果是一個隨機值

  

並發通信Manage,隊列, 互斥鎖