高级编程技巧 学习笔记
一、线程同步
1.1、实现两个线程一问一答
- 两个线程 “天猫精灵”,“小艾同学”
class XiaoAi(threading.Thread):
def __init__(self):
super().__init__(name='小艾同学')
def run(self):
print(f"{self.name}: 在")
print(f"{self.name}: 你猜现在几点了?")
class TianMao(threading.Thread):
def __init__(self):
super().__init__(name='天猫精灵')
def run(self):
print(f"{self.name}: 小艾同学")
print(f"{self.name}: 现在几点了?")
if __name__ == '__main__':
xiaoai = XiaoAi()
tianmao = TianMao()
tianmao.start()
xiaoai.start()
- 执行结果
想要的结果:
天猫精灵: 小艾同学
小艾同学: 在
天猫精灵: 现在几点了?
小艾同学: 你猜现在几点了?
实际的结果:
天猫精灵: 小艾同学
天猫精灵: 现在几点了?
小艾同学: 在
小艾同学: 你猜现在几点了?
1.2、Condition 解决
- 有几个方法
-
wait(self, timeout=None)
线程等待被唤醒 -
notify(self, n=1)
唤醒某在等待的线程 -
notify_all(self)
唤醒所有在等待的线程 -
wait_for(self, predicate, timeout=None)
等待背某线程唤醒
-
这里主要用 wait 与 notify
-
一定是先等待再唤醒
import threading
class XiaoAi(threading.Thread):
def __init__(self, cond):
super().__init__(name='小艾同学')
self.cond = cond
def run(self):
# self.cond.acquire()
with self.cond:
self.cond.wait()
print("{}:在".format(self.name))
self.cond.notify()
self.cond.wait()
print("{}:你猜猜现在几点了".format(self.name))
self.cond.notify()
# self.cond.release()
class TianMao(threading.Thread):
def __init__(self, cond):
super().__init__(name='天猫精灵')
self.cond = cond
def run(self):
# self.cond.acquire()
with self.cond:
print(f"{self.name}: 小艾同学")
self.cond.notify()
self.cond.wait()
print(f"{self.name}: 现在几点了?")
self.cond.notify()
self.cond.wait()
# self.cond.release()
if __name__ == '__main__':
cond = threading.Condition()
xiaoai = XiaoAi(cond)
tianmao = TianMao(cond)
xiaoai.start()
tianmao.start()
-
调用的顺序很重要,先等待后唤醒
-
调用的顺序取决于先等待线程
import threading
class XiaoAi(threading.Thread):
def __init__(self, cond):
super().__init__(name='小艾同学')
self.cond = cond
def run(self):
with self.cond:
print(f"{self.name}: 在")
self.cond.notify()
self.cond.wait()
print(f"{self.name}: 你猜现在几点了?")
class TianMao(threading.Thread):
def __init__(self, cond):
super().__init__(name='天猫精灵')
self.cond = cond
def run(self):
with self.cond:
print(f"{self.name}: 小艾同学")
self.cond.wait()
print(f"{self.name}: 现在几点了?")
self.cond.notify()
if __name__ == '__main__':
cond = threading.Condition()
xiaoai = XiaoAi(cond)
tianmao = TianMao(cond)
tianmao.start()
xiaoai.start()