Python是我喜欢的一种编程语言,我知道其实有很多人对她是有些不待见的,经常拿所谓的零智商入门、运行速度慢来踩她以及踩使用她的人。对此,我只想说,不要和愚者争论。
在我看到一些简洁优雅的代码实现时,总是不由得内心一阵赞叹,这些简洁优雅不仅仅体现在代码的展现形式,还体现在其对自然世界真实逻辑的复现之美。本文拿一个例子来和大家一起分享一下Python的美妙之处吧。
多线程编程每种语言都有其对应的实现,确很少有初学者一看就心中了然的,但是Python真的能做到一看就懂,我们来写一个躲猫猫的例子,一个躲,一个找,躲的人和找的人会有一些交互,会有一些重叠存在时间,看看Python是如何实现的:
import time
import random
import threading
from concurrent.futures import ThreadPoolExecutor
cv_put = threading.Condition()
cv_get = threading.Condition()
found = False
state = False
def hider():
global state
state = True
with cv_put:
cv_put.notify_all()
print("我藏好啦!")
with cv_get:
if cv_get.wait_for(lambda:found==True,timeout=30):
print("找到啦,游戏结束。")
else:
print("没找到,游戏结束。")
def finder(spend_time):
def find_my_friend(spend_time):
time.sleep(spend_time)
return random.choice([True,False])
with cv_put:
if cv_put.wait_for(lambda:state==True,timeout=60):
time.sleep(1)
print("我来找啦!")
if find_my_friend(spend_time):
global found
found = True
with cv_get:
cv_get.notify_all()
def main():
print("游戏开始:")
num = 10
while num:
print(f"{num}")
time.sleep(1)
num = num - 1
with ThreadPoolExecutor(max_workers=3) as executor:
t1 = executor.submit(hider)
t2 = executor.submit(finder,5)
if __name__ == "__main__":
main()
我们写两个独立的函数体来表现躲藏和寻找,程序运行:
1.主函数开始倒数,倒数结束,只需要ThreadPoolExecutor对象分别开启两个线程,没有一句废话,如果是那种完全相同的任务,还可以用map更加简洁的实现。
2.子线程1设置一个变量state来作为交互信号,标识其躲好了,躲好了之后,就喊上一句(notify_all),告诉对方可以来找了。然后干嘛,等着呗(wait_for)
3.子线程2一直在竖着耳朵听(wait_for),收到notify之后就开始行动了,找到对方之后,向对方喊找到你啦(notify),对方获知后游戏结束。
说明:这个实现过程只是为了说明线程,不是对躲猫猫的精准描述,请忽略细节。
在开启线程之后,with 语法会自动管理线程的关闭,设置两个 threading.Condition() 来让线程之间协作交互,按照条件执行,实现起来简直和自然语言没有区别!逻辑清晰。扩展灵活,体现了Python的简洁胜于复杂之道。
事物本就简单,何必搞得云里雾里,对于Python的这种能力,我只能说,美!