并发通信Manage,队列, 互斥锁

目录

Manage

队列  先入先出

互斥锁


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时,才会解阻塞


 互斥锁

线程间的通信不存在限制,但是会存在资源竞争的问题,即同时执行的线程,公用共享资源的时候,会抢占资源,导致数据乱序

所以需要互斥锁来锁定某些操作

在python的原始解释器Cpython中存在着GIL(Global Interpreter Lock,全局解释器锁)因此在解释器执行Python代码

时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目才会释放GIL。

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



如果不加锁,线程之间会竞争资源,得到的结果是一个随机值

  

原文地址:https://www.cnblogs.com/pywjh/p/9497624.html