Python多线程(二)

引言

上节我们演示了使用线程和不使用线程所造成的不同结果,里面提到一个sleep(6)的事情。忘记的请返回去看看。那为什么我们必须要加一个sleep(6)呢?这是因为如果我们没有阻止主线程继续执行,它将会继续执行下一条语句,然后退出。这样就会导致我们的其它线程得不到执行就已经结束了。
在上节的例子当中,我们并没有写让主线程去等待子线程全部完成后再继续的代码,即我们所说的线程需要某种意义上的同步,在这个例子中我们只是通过sleep(6)实现了另一种形式的伪同步机制。
这个时候你肯定会想,那是不是会有比在主线程中延迟6秒更好的线程管理方式呢?好,这个时候就来引入我们的锁的概念了。

直接看例子,在上节的代码中我们引入锁,替代掉sleep(6)。

from time import sleep,ctime
import _thread
loops = [4,2]
def loop(nloop,nesc,lock):
    print("start loop",nloop,"at:",ctime())
    sleep(nesc)
    print("loop",nloop,"end at:",ctime())
    lock.release() #释放锁
def main():
    print("start at:",ctime())
    locks = []
    nloops = range(len(loops))
    for i in nloops:
        lock = _thread.allocate_lock()
        lock.acquire()
        locks.append(lock)#锁的创建
    for i in nloops:
        _thread.start_new_thread(loop,(i,loops[i],locks[i])) # 启动的时候给他一个锁
for i in nloops:
        while locks[i].locked():pass # 都释放了锁之后继续
print("all end at:",ctime())
if __name__ == "__main__":
    main()

运行后>>>

start at: Sun Sep  9 23:35:59 2018
start loop 1 at: Sun Sep  9 23:35:59 2018
start loop 0 at: Sun Sep  9 23:35:59 2018
loop 1 end at: Sun Sep  9 23:36:01 2018
loop 0 end at: Sun Sep  9 23:36:03 2018
all end at: Sun Sep  9 23:36:03 2018

看起来和我们上节课中的sleep(6)输出是一致的,但是他们本质上是有差别的。在这个例子中我们给每个子线程都分配了一个锁,当它执行结束后,又把该锁给释放掉。
我们来仔细分析一下,在main()中我们首先创建了一个锁的列表,通过使用allocate_lock()函数得到锁的对象,然后通过acquire()方法取得每个锁,说白了就是“把锁锁上”,一旦锁被锁上,就可以把它添加到锁列表中去。然后在后面启动子线程的时候给子线程送过去。这就是我们这节课的核心思想了。
有的同学会有疑问,在上面的例子中为什么不在循环创建锁的时候就顺便创建子线程呢?问的好,原因有二:1、因为我们想要同步线程,所有这里我们不做限制。2、获取锁需要时间,如果线程执行太快会导致在获取到锁之前线程就已经结束了。
更多内容请关注公众号“计算机自学平台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值