进程-同步互斥机制

【同步互斥】

1.同步互斥机制

  1. 目的:
    解决对共有资源操作产生的争夺

  2. 临界资源:
    多个进程或线程都能够操作的资源(例如终端)

  3. 临界区:
    操作临界资源的代码段

  4. 同步:
    同步是一种合作关系,为完成某个任务多进程和多线程之间形成一种协调,
    按照约定或条件依次执行操作临界资源,相互告知资源使用情况。
    (这种协调可能是因为阻塞关系达成的)

  5. 互斥:
    互斥是一种制约关系,当一个进程或者线程进入临界区会进行加锁的操作。
    此时其他进程(线程)再企图使用临界资源时就会阻塞,直到资源被释放才能使用。

2.同步互斥方法:

  • Event 事件:
    from multiprocessing import Event
  1. 创建事件对象:
    e = Event()
  2. 事件阻塞:
    e = wait([timeout])
  3. 事件设置:
    e.set()
    对事件对象进行设置,此时wait判断如果事件被set则结束阻塞
    e处于设置状态,e.wait()不在阻塞
  4. 事件清除:
    e.clear()
    e处于未设置状态,e.wait()阻塞
  5. 事件判断:
    e.is_set()
    判断e的当前状态.检测对象是否被设置,设置返回True,事件阻塞为False

示例1:

# event_test.py  
from multiprocessing import Event  
  
# 创建事件对象  
e = Event()  
print(e.is_set())  
e.set()  
# 将设置清除 wait又堵塞  
e.clear()  
e.wait()  
print(e.is_set())  

示例2:

from multiprocessing import Process,Event
from time import sleep

def wait_event():
    print('想操作临界区但是要等待事件设置')
    e.wait()
    print('终于轮到我操作临界区了',e.is_set())

def wait_event_timeout():
    print('也想操作临界区但是也要等2秒吧')
    e.wait(2)
    print('2秒到了我不等了',e.is_set())

e = Event()
p1 = Process(target=wait_event)
p2 = Process(target=wait_event_timeout)

p1.start()
p2.start()

print('假装主进程在操作临界资源')
sleep(3)
e.set()
print('开放临界资源')

p1.join()
p2.join()
--------------------------------------
假装主进程在操作临界资源
想操作临界区但是要等待事件设置
也想操作临界区但是也要等2秒吧
2秒到了我不等了 False
开放临界资源
终于轮到我操作临界区了 True
----------------------------------------------------------------------

  • 锁 Lock
    from multiprocessing import Lock
  1. 创建锁对象:
    lock = Lock()
  2. 上锁:
    lock.acquire() 上锁
  3. 解锁:
    lock.release()
    上锁状态:此时执行acquire()操作会阻塞
    解锁状态:执行acquire()操作为非阻塞
  4. with lock:----> 上锁


    -----> with代码段结束后自动解锁

示例:

from multiprocessing import Process,Lock
import sys
from time import sleep

# sys.stdout标准输出流作为所有进程的临界资源

def writer1():
    # 上锁
    lock.acquire()
    for i in range(5):
	sleep(1)
	sys.stdout.write('writer1输出\n')
	# write不会自动换行,所以加上\n
    # 解锁
    lock.release()

def writer2():
    # with方式上锁
    with lock:
	for i in range(5):
	    sleep(1)
	    sys.stdout.write('writer2输出\n')
	    # with代码段结束后自动解锁

# 创建锁
lock = Lock()

w1 = Process(target=writer1)
w2 = Process(target=writer2)

w1.start()
w2.start()

w1.join()
w2.join()
在终端打印结果:
# 输出5个writer1,输出5个writer2.谁先抢占到谁先输出5个
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章