• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

python实现多进程并发控制Semaphore与互斥锁LOCK

python 搞代码 4年前 (2022-01-09) 21次浏览 已收录 0个评论

一、了解锁

应用场景举例描述: Lock 互斥锁:举例说明?有三个同事同时需要上厕所,但是只有一间厕所,将同事比作进程,多个进程并打抢占一个厕所,我们要保证顺序优先, 一个个来,那么就必须串行,先到先得,有人使用了,就锁住,结束后剩余的人继续争抢

1、利用Lock来处理

模拟三个同事抢占厕所

from multiprocessing import Process
from multiprocessing import Lock
import time
import random

def task1(p, lock):
    # 上锁
    lock.acquire()
    print(f'{p} 开始排泄')
    time.sleep(random.randint(1, 3))
    print(f'{p} 排泄结束')
    # 解锁
    lock.release()

def task2(p, lock):
    lock.acquire()
    print(f'{p} 开始排泄')
    time.sleep(random.randint(1, 3))
    print(f'{p} 排泄结束')
    lock.release()

def task3(p, lock):
    lock.acquire()
    print(f'{p} 开始排泄')
    time.sleep(random.randint(1, 3))
    print(f'{p} 排泄结束')
    lock.release()


if __name__ == '__main__':
    # 实例化一个锁对象
    mutex = Lock()
    # 将锁以参数的形式传入进程对象
    p1 = Process(target=task1, args=('task1', mutex,))
    p2 = Process(target=task2, args=('task2', mutex,))
    p3 = Process(target=task3, args=('task3', mutex,))

    p1.start()
    p2.start()
    p3.start()

执行结果:

# 输出结果:三个进程开始争抢互斥锁,先抢到的先执行,执行结束后,释放掉锁,剩下的继续争抢
task1本文来源gaodai$ma#com搞$$代**码网 开始排泄
task1 排泄结束
task2 开始排泄
task2 排泄结束
task3 开始排泄
task3 排泄结束

1、 注意:

  • 互斥锁在函数中,lock.acquire()上锁一次就要lock.release()解锁一次,在上锁与解锁之间写需要执行的代码。
  • 如果连续上锁两次以上,就会出现死锁现象,代码将不继续执行下去。必须是锁一次解一次。

2、 lock和join比较:

  • 共同点——都可以把并行变成串行,保证了执行顺序
  • 不同点——join是人为设定了顺序,lock是让其争抢顺序,保证了公平性

2、利用反射,来优化上面的代码

上面的代码虽然起到了先进先出,一进一出的效果,但是并不完美。总所周知,我们上厕所是谁先抢到谁先上,并不是说按照代码里start()顺序执行。应该由先抢占到的进程限制性才更合理。

from multiprocessing import Process
from multiprocessing import Lock
import time
import random
import sys

def task1(p, lock):
    # 上锁
    lock.acquire()
    print(f'{p} 开始打印')
    time.sleep(random.randint(1, 3))
    print(f'{p} 打印结束')
    # 解锁
    lock.release()

def task2(p, lock):
    lock.acquire()
    print(f'{p} 开始打印')
    time.sleep(random.randint(1, 3))
    print(f'{p} 打印结束')
    lock.release()

def task3(p, lock):
    lock.acquire()
    print(f'{p} 开始打印')
    time.sleep(random.randint(1, 3))
    print(f'{p} 打印结束')
    lock.release()


if __name__ == '__main__':
    slock = Lock()
    for i in range(1,4):
       p = Process(target=getattr(sys.modules[__name__], f'task{i}'), args=(f'task{i}', slock))
       p.start()

输出结果:

task2 开始打印
task2 打印结束
task3 开始打印
task3 打印结束
task1 开始打印
task1 打印结束

二、进程并发控制 semaphore

semaphore(信号量):用来控制对共享资源的访问数量,可以控制同一时刻并发的进程数
信号量: 也是一把锁,但是不保证数据安全性,同时开启多个线程,但是规定了同时并发执行的上限,后面走多少,进多少。(用于控制并发数量)

1.多进程控制示例(1)

# 举例说明:一间厕所有5个坑位,最多只能同时有5个人上厕所,当前时刻有20个人想上厕所,但是只能让5个人进去,然后出来多少个,才能进去多少个上厕所

# 从一个模块引用多个功能的时候,用逗号隔开
from threading import Semaphore, Thread, currentThread
import time
import random

sem = Semaphore(3)             # 并发执行数设置为5

def task():
    sem.acquire()
    print(f'{currentThread().name}')
    time.sleep(random.randint(1,3))
    sem.release()

if __name__ == '__main__':
    for i in range(20):
        t = Thread(target=task)
        t.start()

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python实现多进程并发控制Semaphore与互斥锁LOCK
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址