Python的线程20 强迫症患者之Barrier类

364 阅读3分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

正式的Python专栏第57篇,同学站住,别错过这个从0开始的文章!

这篇继续介绍threading库里面的类,threading.Barrier类。

很多人说它是一个栅栏,或者屏障,我更愿意说它是一个强迫症患者。

怎么说呢?它跟参与的线程都杠上了,设置了几个,它就必然等待几个人同时准备好,才肯放行!

什么是Barrier类

Barrier类是一个多线程协调工具,它让多个持有Barrier的线程互相等待。 直到满足Barrier实例指定的n个线程(parties参数数值),也就是达到n个线程都调用了Barrier对象的wait方法。
然后这些线程才能同时进入下一个阶段。

阅读Threading库的源码,可以看到原来这玩意是受到Java的CyclicBarrier的启发(这个学委以前也经常用到)才引入到Python中来的。

所以说,很多语言其实是互相促成,互相成长的(互相吸收精华,消除自身劣势的)。

我们作为开发者,应该是看哪个语言在哪个场景下工作最适合来选择。

而非不假思索,就一口咬定,Python就是比啥啥啥好,Java就是比啥啥啥好。

从这些语言的发展,我们应该学习到的是:取长补短,见贤思齐!(这才是最有生命力,最有活力的)

屏幕快照 2022-01-28 下午11.33.23.png

不小心扯远了。

我们看看它的构造方法:

def __init__(self, parties, action=None, timeout=None):
    """Create a barrier, initialised to 'parties' threads."""
    self._cond = Condition(Lock())
    self._action = action
    self._timeout = timeout
    self._parties = parties
    self._state = 0 #0 filling, 1, draining, -1 resetting, -2 broken
    self._count = 0

学委删除了一下参数的注释,意思是这样的thread.Barrier(parties=带屏蔽的线程数量)

其他参数后面的文章还会说。

下面准备了一个程序:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/28 11:44 下午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : testthreadingbarrier1.py
# @Project : hello
import threading

barrier = threading.Barrier(10)


def prepare_before_run(barrier):
    print("运动员准备 - %s" % threading.current_thread().name)
    barrier_counter = barrier.wait()
    print("remaining: %s" % barrier_counter)


threads = []
for i in range(9):
    t = threading.Thread(name="运动员" + str(i + 1), target=prepare_before_run, args=(barrier,))
    threads.append(t)

for t in threads:
    t.start()
for t in threads:
    t.join()

print("学委的Demo程序结束")

这个程序创建了参与线程数位10的一个Barrier对象。然后启动了9个线程获取Barrier对象,准备好后,执行wait方法。

运行效果如下:

屏幕快照 2022-01-28 下午11.54.52.png

如Barrier所设计的功能一样,所有运动员线程都进入等待。

他们在等待第十个运动员到场(并执行wait函数),才开始竞赛。

如果读者把代码中的线程数9改为10,那么程序不会一直等待。

Barrrier保障了全员到齐之后,才放行的效果。

屏幕快照 2022-01-29 上午12.00.51.png

感受到了Barrier的特殊用途了吧。

总结

Barrier类实现代码之前分享的几个threading的类源码设计上复杂多了。

其实吧,Barrier也是学委前面文章说到一个主裁判。

但是,确实它的设计很独到,本篇简单展示一下,务必搞懂,下一篇还是继续讲解Barrier类。

喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏

持续学习持续开发,我是雷学委!
编程很有趣,关键是把技术搞透彻讲明白。
欢迎关注微信,点赞支持收藏!