(5)进程--锁和信号量

#同一时间允许一个进程上一把锁 就是Lock

加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。

#同一时间允许多个进程上多把锁 就是[信号量Semaphore]

信号量是锁的变形: 实际实现是 计数器 + 锁,同时允许多个进程上锁

# 互斥锁Lock : 互斥锁就是进程的互相排斥,谁先抢到资源,谁就上锁改资源内容,为了保证数据的同步性

# 注意:多个锁一起上,不开锁,会造成死锁.上锁和解锁是一对.如下就会形成死锁

lock.acquire()
lock.acquire()
lock.release()
print(123)

(1)单个锁Lock

语法:

from multiprocessing import Process,Lock

lock = Lock() 实例化一把锁

lock.acquire() 上锁

lock.release() 解锁

例:现在模拟一个抢票程序,每次自允许一个人进行修改数据

 1 # 假设现在有数据{"count":3},有3张票
 2 import json
 3 import time
 4 from multiprocessing import Process, Lock
 5 
 6 def search(person):
 7     with open("ticket", mode="r") as fp:
 8         dic = json.load(fp)
 9         # print(dic,type(dic))
10         print("%s 查询余票:%s" % (person, dic["count"]))
11 
12 def get_ticket(person):
13     with open("ticket", mode="r") as fp:
14         dic = json.load(fp)
15     time.sleep(0.5)
16     if dic["count"] > 0:
17         print("%s买到了" % (person))
18         dic["count"] -= 1
19         # 重新更新数据库
20         with open("ticket", "w") as fp:
21             json.dump(dic, fp)
22     else:
23         print("%s没买到这个票" % (person))
24 
25 
26 # 作为统一的并发调用
27 def ticket(person, lock):
28     # 查询票数
29     search(person)
30     # 上锁   到上锁的时候是同步程序
31     lock.acquire()  # 上锁
32     get_ticket(person)
33     lock.release()  # 解锁
34 
35 
36 if __name__ == "__main__":
37     lock = Lock()
38     for i in range(10):
39         # 这里是异步并发
40         p = Process(target=ticket, args=("person%s" % i, lock))
41         p.start()
View Code
#执行结果
person2 查询余票:3
person1 查询余票:3
person3 查询余票:3
person0 查询余票:3
person4 查询余票:3
person6 查询余票:3
person9 查询余票:3
person7 查询余票:3
person8 查询余票:3
person5 查询余票:3
person2买到了
person1买到了
person3买到了
person0没买到这个票
person4没买到这个票
person6没买到这个票
person9没买到这个票
person7没买到这个票
person8没买到这个票
person5没买到这个票
View Code

 

(2)多个锁Semaphore

语法:

from multiprocessing import Process,Semaphore

sem = Semaphore(4) 可以传参,指定多把锁

sem.acquire() 上锁

sem.release() 解锁

 例:模拟ktv唱歌 假设一共10个人,同一时间允许4个人唱歌

from multiprocessing import Process,Semaphore
import random,time

def ktv(person,sem):
    sem.acquire()
    print("%s进入了ktv" % (person))
    time.sleep(random.randrange(6,8))
    print("%s走出了ktv" % (person))
    sem.release()
if __name__ == "__main__":
    # 最多允许4个进程同时上锁
    sem = Semaphore(4)
    for i in range(10):
        p = Process(target=ktv,args=("person%s" % (i),sem))
        p.start()
View Code
person0进入了ktv
person1进入了ktv
person2进入了ktv
person3进入了ktv
person0走出了ktv
person4进入了ktv
person2走出了ktv
person6进入了ktv
person3走出了ktv
person5进入了ktv
person1走出了ktv
person7进入了ktv
person4走出了ktv
person8进入了ktv
person6走出了ktv
person9进入了ktv
person5走出了ktv
person7走出了ktv
person8走出了ktv
person9走出了ktv
View Code
原文地址:https://www.cnblogs.com/lyj910313/p/10787200.html