python进程同步控制,信号量,事件

Posted Hear7

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python进程同步控制,信号量,事件相关的知识,希望对你有一定的参考价值。

#进程同步(multiprocessing.Lock  multiprocessing.Semaphore multiprocessing.Event

#在计算机中,有一些硬件和软件,例如处理器,打印机,都属于竞争类资源.当有需求时,很多
#进程都有争抢这些资源,而对于这类资源,就属于临界资源.当多进程共同处理某一个数据时,
# 这个数据也就属于一个临界资源.操作系统对计算机内部各种资源都使其在竞争中有序,但对数据来说,尤其是动态数据,处理是
# 就变成临界资源,需要对临界资源加以保护,否者会出现数据混乱现象


#<<<<<<锁   multiprocessing.Lock
#程序实现了异步,它们之间没有顺序,一旦开启不受控制
#当多个子进程使用同一份数据资源的时候,就会引发数据安全或者顺序混乱问题

#  多进程抢占资源
#
# from multiprocessing import Process
# import random,time
#
# def func(addr):
#     print("我是%s"%addr)
#     time.sleep(random.random())
#     print("谢谢")
#
# if __name__ == ‘__main__‘:
#     lst = ["湖北的",‘北京的‘,‘山西的‘,‘河北的‘]
#     for addr in lst:
#         p = Process(target=func,args=(addr,))
#         p.start()
#     #time.sleep(2)
#     print(‘我选%s‘%random.choice(lst))


#结果:
# 我选湖北的  $  主进程抢
# 我是湖北的
# 我是北京的
# 我是山西的
# 我是河北的
# 谢谢
# 谢谢
# 谢谢
# 谢谢

#抢占输出资源的事情,是指多进程并发执行时,并不是一个进程执行完任务后其他进程再执行

#  使用锁维护输出资源
# from multiprocessing import Process,Lock
# import time,random
#
# def func(addr,lock):
#     lock.acquire()
#     print("我是%s" %addr)
#     time.sleep(random.random())
#     print("谢谢")
#     lock.release()
# if __name__ == ‘__main__‘:
#     lock = Lock()
#     lst = ["湖北的",‘北京的‘,‘山西的‘,‘河北的‘]
#     for addr in lst:
#         p = Process(target=func,args=(addr,lock))
#         p.start()
#     time.sleep(4)
#     print("

我选%s"%random.choice(lst))
# 结果:  正常结果,输入所有人的名单,再选人
# 我是湖北的
# 谢谢
# 我是北京的
# 谢谢
# 我是山西的
# 谢谢
# 我是河北的
# 谢谢
#
#
# 我选山西的

#注意:使用加锁的形式确保了程序的顺序执行,但是执行又变成了串行,降低了效率,但是安全


# 模拟12306多人抢票问题
#
# from multiprocessing import Process,Lock
# import json
# import time
# def check(i):  #查票
#     with open(‘info‘) as f:
#         con = f.read()
#     print(‘第%s个人在查票,余票为%s‘ %(i,con))
#
#
# def pay(i,l):  #买票
#     l.acquire()
#     with open(‘info‘) as f:
#         con = int(f.read())
#     time.sleep(0.01)
#     if con:
#         print(‘33[31m 第%s个人买到票了 33[0m‘%i)
#         con -= 1
#     else:
#         print(‘33[032m 第%s个人没买到票33[0m‘%i)
#     with open(‘info‘,"w") as f:
#         f.write(str(con))
#     l.release()
#
# if __name__ == ‘__main__‘:
#     l = Lock()
#     for i in range(10):    # 多用户查看票数
#         p = Process(target=check,args=(i+1,))
#         p.start()
#     for i in range(10):  # 多用户并发购买票
#         p_buy = Process(target=pay,args=(i+1,l))
#         p_buy.start()
# 加锁可以保证多个进程修改同一块数据,同时只能有一个任务可以进行修改
#即串行的修改,速度慢,但是保证了数据的安全性
#注意:
    #虽然可以用文件共享数据实现进程间的通信,但是效率低,需要自己加锁处理

#因此我们最好找寻一种解决方案能够兼顾:
    # 1、效率高(多个进程共享一块内存的数据)
    # 2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。
    # 队列和管道都是将数据存放于内存中
    # 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,
    # 我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,
    # 而且在进程数目增多时,往往可以获得更好的可获展性。


#<<<<<<<<<<信号量>>>>>..
#互斥锁只允许一个线程更改数据,而信号量Semaphore是同时允许一定数量的线程更改数据

# s = Semaphore(n)
# n是指初始化一把锁配n把钥匙,一个int型
# 拿钥匙锁门 s.acquire()
# 还钥匙开门 s.release()
# 信号量机制比锁机制多了一个计数器,这个计数器是用来记录当前剩余几把钥匙的
# 当计数器为0时,表示没有钥匙,此时acquire()处于阻塞状态
# 对于计数器来说每acquire()一次计算器内部就减1,release()一次,计数器就加1

# from multiprocessing import Process,Semaphore
# import time,random
#
# def work(sem,i):
#     sem.acquire()
#     print(‘%s占到一个房间‘%i)
#     time.sleep(random.random())    #  模拟在房间中待的时间
#     sem.release()
#
# if __name__ == ‘__main__‘:
#     sem = Semaphore(8)   # 配四把钥匙
#     lst = []
#     for i in range(10):
#         p = Process(target=work,args=(sem,i))
#         p.start()
#         lst.append(p)
#     [i.join() for i in lst]
#     print(">>>>>>>>>")


#   <<<<事件>>>>>
# python线程的事件用于主线程控制其它线程的执行,事件主要提供三个方法 set,wait,clear
# 事件处理的机制:is_set() 方法的值,默认为False ,那么程序执行event.wait方法时会阻塞
#如果is_set()值为True是,那么event.wait方法执行是便不阻塞

# clear()方法:将is_set()的值设置为False
# set()方法:将is_set()的值设置为True


#  红绿灯控制实例

from multiprocessing import Process,Event
import time,random

def light(e):

    while 1:
        if e.is_set():
            e.clear()
            print("33[031m红灯亮了33[0m")
        else:
            e.set()
            print("33[032m绿灯亮了33[0m")
        time.sleep(2)

def cars(i,e):
    if not e.is_set():
        print("第%s辆车过去了" % i)
        e.wait()
    print("第%s辆车过去了" %i)
if __name__ == ‘__main__‘:
    e = Event()
    p = Process(target=light,args=(e,))   #  红灯进程
    p.start()
    for i in range(50):
        car = Process(target=cars,args=(i+1,e))
        car.start()
        time.sleep(random.random())

#
#
# from multiprocessing import Process, Event
# import time
# import random


# 亮灯和车行驶是异步的
# 亮灯的进程先开启
# is_set()刚开始默认为False
# 先开始l绿灯亮,这个时候car的进程开启,is_set()为True,可以过车
#
# def light(e):
#     while 1:
#         if e.is_set():
#             e.clear()
#             print(‘33[31m红灯亮了33[0m‘)
#         else:
#             e.set()
#             print(‘33[32m绿灯亮了33[0m‘)
#         time.sleep(2)
#
#
# def cars(i, e):
#     if not e.is_set():
#         print(‘第%s辆车在等待‘ % i)
#         e.wait()
#     print(‘第%s辆车过去了‘ % i)
#
#
# if __name__ == ‘__main__‘:
#
#     e = Event()
#     tr = Process(target=light, args=(e,))  # 创建一个进程控制红绿灯
#     tr.start()
#
#     for i in range(50):  # 创建50个进程代表50辆车
#         car = Process(target=cars, args=(i + 1, e))
#         car.start()
#         time.sleep(random.random())
#

  

以上是关于python进程同步控制,信号量,事件的主要内容,如果未能解决你的问题,请参考以下文章

Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁信号量事件队列生产者消费者模型

python 管道 事件 信号量 进程池(map/同步/异步)回调函数

Python下进程同步之互斥锁信号量事件机制 𪕽

第34篇 通过类的方法开启子进程,以及传参,join阻塞,daemon守护进程,同步Lock,Samphore信号量,event事件

进程/线程同步的方式和机制,进程间通信

Python下进程同步之互斥锁信号量事件机制 -- 2019-08-16 17:58:28