摘至本人有道云笔记《Python线程》
在Python中,同样可以实现多线程,有两个标准模块thread和threading,不过我们主要使用更高级的threading模块
Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local。
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
threading.TIMEOUT_MAX 设置threading全局超时时间
Thread是线程类,有两种使用方法,直接传入要运行的方法或从Thread继承并覆盖run()
1)将要执行的方法作为参数传给Thread的构造方法
构造方法:
Thread(group=None, target=None, name=None, args=(), kwargs={})
group: 线程组,目前还没有实现,库引用中提示必须是None;
target: 要执行的方法;
name: 线程名;
args/kwargs: 要传入方法的参数。
实例方法:
isAlive(): 返回线程是否在运行。正在运行指启动后、终止前。
get/setName(name): 获取/设置线程名。
is/setDaemon(bool): 获取/设置是后台线程(默认前台线程(False))。(在start之前设置)
如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止
如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
start(): 启动线程。
join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
例1:验证了serDeamon(False)(默认)前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,主线程停止。
使用循环创建多线程
例2:继承线程类,子类创建线程
使用此方法创建线程,注意两点:
1)重写父类的__init__方法,并调用父类的__init__方法
2)实例化子类对象就是创建子线程,使用子线程对象m的start方法启动的是,子类里的run方法(线程要做的事)。
1)线程锁
由于多个线程之间可以共享数据,那随之而来的问题就是:多个线程同时更改一个变量、使用一个资源时,就会出现数据错乱、死锁等现象。
下面是数据错乱的例子:
理论上如果顺序执行,change方法的每次计算结果都是0。由于两个线程都在同时访问change方法,就会造成数据错乱。
对于该问题,出现了Lock。 当访问某个资源之前,用Lock.acquire()锁住资源,访问之后,用Lock.release()释放资源。
获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。所以用try...finally来确保锁一定会被释放。
多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。