python多线程编程,一般使用thread和threading模块。thread模块想对较底层,threading模块对thread模块进行了封装,更便于使用。所有,通常多线程编程使用threading模块。
1. thread线程类基本介绍
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})
应该始终以关键字参数调用该构造函数。参数有:
2. 线程的创建
这个类表示在单独的一个控制线程中运行的一个活动。有两种指定活动的方法:①通过传递一个可调用对象给构造函数,②或在子类中覆盖run()方法。在子类中不应该覆盖其它方法(构造函数除外)。换句话说,就是只覆盖该类的init()和run()方法。
一个线程对象创建后,它的活动必须通过调用线程的start()方法启动。它在单独的一个控制线程中调用run()方法。
(1)通过传递一个可调用对象给构造函数,使用threading.Thread(),实例化一个线程
# coding: utf-8
import threading
# 使用threading.Thread(),实例化一个线程
def fun():
print 'A new thread'
if __name__ == '__main__':
# 创建线程对象
thread = threading.Thread(target=fun)
# 启动线程
thread.start()
(2)创建threading.Thread 的子类, 并覆盖run()方法
# coding: utf-8
import threading
# 创建一个threading.Thread 的子类
class new_Thread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# 覆盖run()方法,这是线程启动后执行的函数
def run(self):
print 'A new thread'
if __name__ == '__main__':
# 创建线程对象
thread = new_Thread()
# 启动线程
thread.start()
3. Thread.join()方法
join([timeout])
等待直至线程终止。它阻塞调用线程直至join()方法被调用的线程终止 – 要么正常地要么通过一个未处理的异常 – 或者直至timeout发生。
当timeout参数存在且不为None时,它应该以一个浮点数指定该操作的超时时间,单位为秒(可以是小数)。由于join()永远返回None,你必须在join()之后调用isAlive()来判断超时是否发生 – 如果线程仍然活着,则join()调用超时。
如果timeout参数不存在或者为None,那么该操作将阻塞直至线程终止。一个线程可以被join()多次。
如果尝试join当前的线程,join()会引发一个RuntimeError,因为这将导致一个死锁。在线程启动之前join()它也是错误的,尝试这样做会引发同样的异常。
# coding: utf-8
import threading
import time
def fun():
time.sleep(1)
print 'A new thread'
if __name__ == '__main__':
thread = threading.Thread(target=fun)
thread.start()
# 线程会阻塞后面的线程,直到次线程结束
thread.join()
# 'end'会在打印完'A new thread'出现,如果没有thread.join(),那么会先打印'end'
print 'end'
4. Thread.setDaemon()方法
当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程就分兵两路,当主线程完成想退出时,会检验子线程是否完成。如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是,只要主线程完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以用setDaemon方法,并设置其参数为True。
# coding: utf-8
import threading
import time
def fun():
time.sleep(1)
print 'A new thread'
if __name__ == '__main__':
thread = threading.Thread(target=fun)
thread.start()
# 线程不会阻塞后面的主线程,主线程会继续执行,如果执行完,程序就直接退出
thread.setdaemon(True)
# 程序只会打印'end',之后就直接退出,不会打印'A new thread'
print 'end'