文章目录
线程同步与线程锁
线程同步
概念
* 线程同步,线程间协同,通过某种技术,让一个线程访问某些数据时,其他线程不能访问这些数据,直到该线程完 成对数据的操作。
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()
-
使用同一个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========")
2.threading.Timer定时器,延迟执行
方法 | 含义 |
---|---|
Timer.cancel() | 取消定时器,(定时器为执行函数时可以取消,在函数执行中无法取消) |
Time.start() | 启动定时器 |
- threading.Timer继承自Thread,这个类用来定义延迟多久后执行一个函数。
class threading.Timer(interval, function, args=None, kwargs=None)
- interval #多少时间后执行function函数
- 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========")
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))