Python中线程同步与线程锁

本文详细介绍了Python中线程同步的相关概念和各种锁机制,包括threading.Event对象、threading.Timer定时器、threading.Lock锁、可重入锁RLock、Condition条件锁、Semaphore信号量以及BoundedSemaphore有界信号量。通过实例展示了它们的使用方法和应用场景,强调了正确使用锁以避免死锁的重要性。
摘要由CSDN通过智能技术生成

线程同步与线程锁

线程同步

概念
* 线程同步,线程间协同,通过某种技术,让一个线程访问某些数据时,其他线程不能访问这些数据,直到该线程完 成对数据的操作。

1.threading.Event对象

  • Event事件,是线程间通信机制中最简单的实现,使用一个内部的标记flag,通过flag的True或False的变化 来进行操作
名称 含义
event.set() 标记设置为True
event.clear() 标记设置为False
event.is_set() 标记是否为True
event.wait(timeout=None) 设置等待标记为True的时长,None为无限等待。等到返回True,未等到超时了返回False
  • 老板雇佣了一个工人,让他生产杯子,老板一直等着这个工人,直到生产了10个杯子
import threading
import time
import logging

logging.basicConfig(format="%(asctime)s %(threadName)s %(thread)s %(message)s",level=logging.INFO)

def worker(event:threading.Event,count = 10):
    logging.info("我是worker工作线程")
    cups = []
    while True:
        logging.info("制作了一个 cup")
        time.sleep(0.2)
        cups.append(1)
        if len(cups)>=count:
            event.set()
            break
    logging.info("制作完成:{}".format(cups))

def boss(event:threading.Event):
    logging.info("我是boss")
    event.wait()
    logging.info("Good Job")

event = threading.Event()
b = threading.Thread(target=boss,args=(event,))
w = threading.Thread(target=worker,args=(event,))
b.start()
w.start()

threading2_001

  • 使用同一个Event对象的标记flag。

  • 谁wait就是等到flag变为True,或等到超时返回False。不限制等待的个数。

  • wait的使用

from threading import Thread,Event
import logging

logging.basicConfig(format="%(asctime)s %(threadName)s %(thread)s %(message)s",level=logging.INFO)

def worker(event:Event,interval:int):
    while not event.wait(interval):
        logging.info("没有等到。。")

e = Event()
Thread(target=worker,args=(e,1)).start()

e.wait(5)
e.set()

print("======end========")

threading2_002

2.threading.Timer定时器,延迟执行

方法 含义
Timer.cancel() 取消定时器,(定时器为执行函数时可以取消,在函数执行中无法取消)
Time.start() 启动定时器
  • threading.Timer继承自Thread,这个类用来定义延迟多久后执行一个函数。
  • class threading.Timer(interval, function, args=None, kwargs=None)
    1. interval #多少时间后执行function函数
    2. function #需要执行的函数
  • start方法执行之后,Timer对象会处于等待状态,等待了interval秒之后,开始执行function函数的。
  • Timer是线程Thread的子类,Timer实例内部提供了一个finished属性,该属性是Event对象。
  • cancel方法,本质上 是在worker函数执行前对finished属性set方法操作,从而跳过了worker函数执行,达到了取消的效果。
from threading import Timer
import logging
import time

logging.basicConfig(format="%(asctime)s %(threadName)s %(thread)s %(message)s",level=logging.INFO)

def worker():
    logging.info("in worker")
    time.sleep(5)
    logging.info("end in worker")

t = Timer(2,worker)
t.setName("timer1") #设置线程名称
# t.cancel() #取消定时器后,定时器不在执行
t.start()
# t.cancel() #取消定时器后,定时器不在执行
time.sleep(4) #等待4秒后,定时器已经开始执行
t.cancel() #当定时器执行后,无法取消

print("======end========")

threading2_003

3.threading.Lock锁

锁(Lock):一旦线程获得锁,其他试图获取锁的线程将被阻塞等待。
锁:凡是存在共享支援争抢的地方都可以使用锁,从而保证只有一个使用者可以完全使用这个资源。

名称 含义
Lock.acquire(blocking=True,timeout=-1) 获取锁,获取成功返回True,否则返回False
当获取不到锁时,默认进入阻塞状态,直到获取到锁,后才继续。阻塞可以设置超时时间。非阻塞时,timeout禁止设置。如果超时依旧未获取到锁,返回False。
Lock.rease() 释放锁,可以从任何线程调用释放。
已上锁的锁,会被设置为unlocked。如果未上锁调用,会抛出RuntimeError异常。
import threading
import sys
import time

def print(*args):
    sys.stdout.write(" ".join(map(str,args))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值