Thread 是threading模块中最重要的类之一,能够正常的运用它来创立线程。有两种办法来创立线程:一种是经过承继Thread类,重写它的run办法;另一种是创立一个threading.Thread目标,在它的初始化函数(__init__)中将可调用目标作为参数传入。下面别离举例阐明。先来看看经过承继threading.Thread类来创立线程的比如:
在代码中,咱们创立了一个Counter类,它承继了threading.Thread。初始化函数接纳两个参数,一个是琐目标,另一个是线程的称号。在Counter中,重写了从父类承继的run办法,run办法将一个全局变量逐个的添加10000。在接下来的代码中,创立了五个Counter目标,别离调用其start办法。最终打印成果。这儿要阐明一下run办法 和start办法: 它们都是从Thread承继而来的,run()办法将在线程敞开后履行,能够把相关的逻辑写到run办法中(一般把run办法称为活动[Activity]。);start()办法用于发动线程。
在这段代码中,咱们界说了办法doAdd,它将全局变量count 逐个的添加10000。然后创立了5个Thread目标,把函数目标doAdd 作为参数传给它的初始化函数,再调用Thread目标的start办法,线程发动后将履行doAdd函数。这儿有必要介绍一下threading.Thread类的初始化函数原型:
获取线程的标识符。线程标识符是一个非零整数,只要在调用了start()办法之后该特点才有用,不然它只回来None。
判别线程是否是激活的(alive)。从调用start()办法发动线程,到run()办法履行完毕或遇到未处理反常而中止 最近一段时刻内,线程是激活的。
调用Thread.join将会使主调线程阻塞,直到被调用线程运转完毕或超时。参数timeout是一个数值类型,表明超时时刻,假如未供给该参数,那么主调线程将一向阻塞到被调线程完毕。下面举个比如阐明join()的运用:
在threading模块中,界说两种类型的琐:threading.Lock和threading.RLock。它们之间有一点纤细的差异,经过比较下面两段代码来阐明:
这两种琐的首要差异是:RLock答应在同一线程中被屡次acquire。而Lock却不答应这样的一种状况。留意:若运用RLock,那么acquire和release有必要成对呈现,即调用了n次acquire,有必要调用n次的release才干真实开释所占用的琐。
能够把Condiftion理解为一把高档的琐,它供给了比Lock, RLock更高档的功用,答应咱们也能够操控杂乱的线程同步问题。threadiong.Condition在内部保护一个琐目标(默许是RLock),能够在创立Condigtion目标的时分把琐目标作为参数传入。Condition也供给了acquire, release办法,其意义与琐的acquire, release办法共同,其实它仅仅简略的调用内部琐目标的对应的办法罢了。Condition还供给了如下办法(特别要留意:这一些办法只要在占用琐(acquire)之后才干调用,不然将会报RuntimeError反常。):
wait办法开释内部所占用的琐,一起线程被挂起,直至接纳到告诉被唤醒或超时(假如供给了timeout参数的话)。当线程被唤醒并从头占有琐的时分,程序才会持续履行下去。
唤醒一个挂起的线程(假如存在挂起的线程)。留意:notify()办法不会开释所占用的琐。
唤醒一切挂起的线程(假如存在挂起的线程)。留意:这一些办法不会开释所占用的琐。
现在写个捉迷藏的游戏来详细介绍threading.Condition的根本运用。假定这样的游戏由两个人来玩,一个藏(Hider),一个找(Seeker)。游戏的规矩如下:1. 游戏开端之后,Seeker先把自己眼睛蒙上,蒙上眼睛后,就告诉Hider;2. Hider接纳告诉后开端找当地将自己藏起来,藏好之后,再告诉Seeker能够找了; 3. Seeker接纳到告诉之后,就开端找Hider。Hider和Seeker都是独立的个别,在程序顶用两个独立的线程来表明,在游戏过程中,两者之间的行为有必定的时序联系,咱们经过Condition来操控这种时序联系。
阻塞线程,直到Event目标内部标识位被设为True或超时(假如供给了参数timeout)。
下面运用Event来完成捉迷藏的游戏(可能用Event来完成不是很形象)
threading模块的内容许多,一篇文章很难写全,更多关于threading模块的信息,请查询Python手册 threading模块。