进程同步与互斥实验代码_python笔记46:进程同步机制:互斥锁与信号量

主要内容:

  • 小目标:掌握进程同步机制
  • 主要内容:Lock

如果看完这篇文章,你还是搞不懂并发同步及锁机制,

你来找我,我保证不打你,我给你发100的大红包。

1. 同步机制

  • 并发编程中存在异步问题,如何处理?

使用同步机制,

常见的同步机制包括锁,信号量;

同步机制: 一个例子:公共资源,互斥锁,AB两个进程

修改公共资源流程

进程修改公共资源,需要获取锁;

修改资源;

释放锁;

两个进程:

A进程获取锁,同时去修改公共资源;

进程调度切换,执行B进程;

B进程去获取锁,但是A进程已经占有锁,B进程被挂起;

A进程修改完毕,释放锁;

B进程被唤起,修改资源并释放锁;

2. Value与Array自带锁机制

Value与Array创建对象参数:

Value(typecode_or_type, *args, lock=True)Array(typecode_or_type, size_or_initializer, *, lock=True)

lock默认值为True:代表支持锁机制;

相关方法:

b8c2770b7d58db1c0394856eb459dcfe.png

Value自带锁机制

使用方式:

lock = val.get_lock()#打印lock信息print(lock)val.acquire()#打印lock信息print(lock)val.value = 100val.release()

结果:每次lock之后,锁会显示状态;

3. 锁机制应用

两个进程使用同步机制对Value对象修改:

主进程加100000次;子进程减100000次;

代码如下:

import multiprocessingfrom multiprocessing import Queuefrom multiprocessing import Value, Arrayg_value = Value('i', 0)#对g_value处理封装成函数def deal(gvalue, val):    gvalue.acquire()    gvalue.value += val    gvalue.release()#进程函数, 共享内存必须通过参数传入def func(gvalue):    i = 0    while i < 100000:        #加1        deal(gvalue, 1)        i += 1if __name__ == "__main__":    print("g_value init value:", g_value.value)    #全局消息队列    main_msgq = Queue()    #消息队列必须通过参数传入到子进程,否则无效    p = multiprocessing.Process(target=func, args=(g_value,))    p.start()    i = 0    while i < 100000:        #减1        deal(g_value, -1)        i += 1    p.join()    print("g_value  end value:", g_value.value)

结果:符合预期,最后g_value的值为0;

g_value init value: 0g_value  end value: 0

4. 重入锁:Lock

  • Lock相关方法:

方法说明:

de29ea314d659d045f1398d0c9b77561.png

重入锁

一个例子:

lock = Lock()lock.acquire()#此处处理公共资源lock.release()

注意:

acquire与release必须成对出现;

lock.acquire中可以设置非阻塞模式:block=False,如果获取失败返回False

  • 死锁问题

一个进程获取锁之后,再次获取,就会造成死锁; 例:

lock = Lock()lock.acquire()lock.acquire()#处理公共资源lock.release()lock.release()

一般没人这么做,但是有人这么做:

lock = Lock()lock.acquire()def do():    lock.acquire()    #处理公共资源    lock.release()lock.release()

解决方式:重入锁;

5. 冲入锁:RLock

RLock:可以被一个程多次获取; 使用方式与Lock类似; 例如:

rlock = RLock()rlock.acquire()rlock.acquire()print(rlock)rlock.release()rlock.release()print('over')

不会死锁

6. 信号量:Semaphore

Semaphore:可以设置同时被占有的次数;

相关方法:

56468e56a06fe523fcb90a69deb9cd8d.png

信号量

Semaphore使用方式与Lock类似,但是它可以指定被占有次数; 例如:

sem = Semaphore(2)print('init:', sem.get_value())sem.acquire()print('acquire 1:', sem.get_value())sem.acquire()print('acquire 2:', sem.get_value())sem.release()print('release 1:', sem.get_value())sem.release()print('release 2:', sem.get_value())

结果:

init: 2acquire 1: 1acquire 2: 0release 1: 1release 2: 2

总结:

  • Lock,RLock,Semaphore原理与使用方式类似,在掌握Lock后,在理解其他就比较容易;
  • 互斥所,信号量这种同步机制在其他一些语言中也同样适用;
  • Lock,RLock适用于同一时刻只能一个进程占有场景;
  • Semaphore比较灵活,可以设置同时占有的数量;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值