1.全局解释器锁定
Python虚拟机使用GIL(Global Interpreter Lock,全局解释器锁定)来互斥线程对共享资源的访问,暂时无法利用多处理器的优势。虽然python解释器可以“运行”多个线程,但在任意时刻,不管有多少的处理器,任何时候都总是只有一个线程在执行。对于I/O密集型任务,使用线程一般是没有问题的,而对于涉及大量CPU计算的应用程序而言,使用线程来细分工作没有任何好处,用户最好使用子进程和消息传递。
2.threading
python的threading模块提供Thread类和各种同步原语,用于编写多线程的程序。
2.1. Thread(target=None,name=None,args=(),kwargs={})
此函数创建一个Thread实例。target是一个可调用函数,线程启动时,run()方法将调用此对象。name是线程的名称,默认是'Thread-N'的格式。args是传递给target函数的参数元组,kwargs是传递给target函数的关键字参数的字典。
Thread实例t支持以下方法和属性:
- t.start() 启动线程,就是调用run()方法
- t.run() 可以在Thread的子类中重新定义
- t.join([timeout]) 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout(可选参数)。
- t.is_live() 返回线程的活动状态
- t.name 线程的名称
- t.ident 线程标识符
- t.daemon 设置线程是否为守护线程,必须在t.start()前设置。当设置为True时,主线程要退出时,不必等守护线程完成。'
创建线程有两种方法:
- 创建一个Thread实例,传递给它一个函数
1 2 3 4 5 6 7 8 9 |
|
2. 从Thread派生出一个子类,然后创建一个子类的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
后一种方法比较python一点。
由于线程会无限循环,所以设置daemon为True,这样当进程结束时,线程也将被销毁。
例如有个数数程序,一个线程从1数到9,另一个线程从a数到j,每个线程都要耗费9s,如果要顺序执行的话需耗费18s。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
< |