Python多为线程编程提供了两个简单明了的模块:thread和threading,Python3中已经不存thread模块,已经被改名为_thread,实际优先使用
threading模块。
1.Python创建线程的两种方法:
①:创建一个threading.Thread对象,在其初始化函数中将可调用对象作为参数传入
import threading def handle(sid): print("Thread %d run"%sid) #创建线程方法1 for i in range(1, 11): t = threading.Thread(target=handle, args=(i,)) t.start() print("main thread")
②:通过继承Thread类,重写它的run()方法
import threading def handle(sid): print("Thread %d run"%sid) class MyThread(threading.Thread): def __init__(self,sid): threading.Thread.__init__(self) self.sid = sid def run(self): handle(self.sid) for i in range(1,11): t = MyThread(i) t.start() print("main thread")
2.threading.Thread对象:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
group :这个应该为空,是个保留位,是为了以后ThreadGroup(线程组)这个类实现而预留的
target:是个由run()方法执行调用的可调用对象,也就是线程要执行的函数,默认为空,意味着没有东西可以被调用
name: 这个参数表示线程的名称,默认情况下,是一个类似于Thread-N形式的名字,这里的N是小的十进制失踪
args: 这是个参数元组,是用来给target调用的,默认为一个空的元组
kwargs={} : 这是个关键字参数组成的字典,是用来给target调用的,默认为一个空的字典
daemon 这个bool值表明这个线程是否是守护进程,当为True时,就是个守护进程,否则为False,就不是守护进程
这个必须在start()之前被设置,否则就会抛出RuntimeError异常,它的初始值继承于创建它的线程,如果主进程不是守护进程,
那么由主进程创建的子进程默认都不是守护进程
3.start方法与run方法
启动线程是调用start方法,而不调用run方法,这里两者有什么区别呢
首先线程的状态有五种:创建、就绪、运行、阻塞和死亡
当调用start函数,线程的状态就处于就绪状态,处于就绪状态后,还需要等待CPU分配时间片
如果分到时间片,就进入运行状态,执行run函数
start() --> 启动线程,这个函数只能在一个线程中调用一次,如果超过一次则会抛出RuntimeError异常,它安排run()方法在另一个线程中调用
run() --> 用以表示线程活动的方法,你可以在子线程中覆盖此方法
import threading class MyThread(threading.Thread): def __init__(self,sid): threading.Thread.__init__(self) self.sid = sid def run(self): currentTreadname = threading.currentThread() print("running in", currentTreadname) t = MyThread(1) t.start() t.run()
输出结果:
running in <MyThread(Thread-1, started 4948)> running in <_MainThread(MainThread, started 5276)>
可以看到调用start方法是在创建的子线程中调用,而直接调用run方法则是在主线程中调用