上一篇文章讲了python多线程的基础知识和thread模块,这一篇着重讲解一下threading模块
threading模块
threading模块除了Thread类之外,好包括其他很多的同步机制,下面来看一下threading模块汇总所包含的对象。
对象
描述
Thread
执行线程的对象
Lock
锁对象
RLock
递归锁,是一个线程可以再次拥有已持有的锁对象
Condition
条件变量对象,使一个线程等待另一个线程满足特定的条件触发
Event
事件对象,普通版的Condition
Semaphore
信号量,为线程间共享的资源提供一个“计数器”,计数开始值为设置的值,默认为1
BoundedSemaphore
与Semaphore相同,有边界,不能超过设置的值
Timer
定时运行的线程对象,定时器
Barrier
界限,当达到某一界限后才可以继续执行
看到threading有这么多对象,是不是有些懵了,下面一个个的来看一下
Thread类
Thread类是threading模块的主要主要执行对象。Thread对象有三个数据属性,name(线程名)、ident(线程的标识)、daemon(布尔值,是否是守护线程)。这三个数据属性可以直接通过对象进行调用并进行设置。
守护线程一般是一个等待客户端请求服务的服务器,进程退出时,该线程在正常情况下不会退出
Thread类还有一些对象方法
对象方法
描述
__init__()
实例化一个线程对象
start()
开始执行线程
run()
定义线程功能方法(一般在子类中进行重写)
join(timeout=None)
直至启动的线程终止或timeout秒,否则一直挂起,多用于主线程进行阻塞等待子线程运行完毕。
isAlivel/is_alive()
线程是否存活
注意
__init__()完整函数如下__init__(group=None,target=None,name=None,args=(),kwargs={},verbose=None,daemon=None),Thread对象实例化需要一个可调用的target(可以是一个函数,也可是一个可调用的类实例),参数args或者kwargs。
说了这么多,那怎么创建线程呢?一般有两种方法:
创建Thread实例,传给其一个函数或可调用的类实例
派生Thread的子类,并创建子类的实例
一般来说,创建Thread实例并传递一个函数和派生Thread子类比较常用,后者更符合面向对象且比较容易扩展
创建Thread实例,传给它一个函数
import random
import threading
from time import ctime,sleep
def loop(nloop,nsec):
print('start loop ',nloop,' sec:',nsec,' at:',ctime())
sleep(nsec)
print('end loop ',nloop,' done at:',ctime())
def main():
print('starting at:',ctime())
threads = []
for i in range(3):
t = threading.Thread(target=loop,args=(i,random.randint(1,5)))
threads.append(t)
for i in range(3):
threads[i].start()
for i in range(3):
threads[i].join()
print('all done at:',ctime())
if __name__ == '__main__':
main()
传递给Thread实例一个函数其实和thread模块中差不多,这里随机生成3个Thread实例,分别运行随机事件,然后通过循环让线程启动threads[i].start(),然后通过join()让主线程等待结束。
打印结果如下
starting at: Thu Sep 7 17:53:44 2017
start loop 0 sec: 1 at: Thu Sep 7 17:53:44 2017
start loop 1 sec: 5 at: Thu Sep 7 17:53:44 2017
start loop 2 sec: 3 at: Thu Sep 7 17:53:44 2017
end loop