Python之多线程
一、概念
1、多任务可以由多进程完成,也可以由一个进程内的多线程完成。
进程是由若干的线程组成,一个进程至少有一个进程。
线程是操作系统直接支持的执行单元,天赐高级预压通常都是内置多线程的支持,Python的线程是真正的POSIX Thread而不是模拟出来的线程。
2、Python的标准库提供两个模块:thread与threading,thread是第几模块,threading是高级模块,对thread的封装,绝大多数的情况下只需要使用threading这个高级模块。
3、启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行。
二、实操
eg: import threading def foo(): pass t=threading.Thread(target=foo) t.start() t.join() print('this is main thread')
任何进程默认情况就会启动一个线程,把该线程称为主线程,主线程又可以启动新的线程。
threading.current_thread()永远返回当前线程的实例。主线程的名字为MainThread,子线程的名字在创建时指定,用LoopThread命名子线程,名字仅仅是在打印的时候会显示。
三、Lock
多线程和进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每一个进程中,互不影响,而多线程中满所有变量都是由所有线程共享。任何一个变量都可以被任何一个线程修改,因此线程之间的共享数据最大的危险在于多线程同时改一个变量,把内容容易改乱,或者出现资源抢占的问题。
threading.Lock()为线程上锁,不会造成修改冲突。
threading.acquire()解锁,其他线程即可获得资源。
一般使用try finally来确保一定使用完后释放锁。
四、多核CPU
虽然Python是真的多线程,但是Python的解释器执行代码的时候有一个GIL锁,任何Python线程执行前,都必须先获得GIL锁,每执行100条字节码,解释器就自动的释放GIL锁,让别的线程有机会执行。
五、ThreadLocal
使用全局变量在方法中使用ThreadLocal对象,每个Thread对它都可以读写属性,但是互不影响。
ThreadLocal最常用的地方就是胃每个线程绑定一个数据库连接。HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便的访问这些资源。
eg: import threading local_school=threading.local()#创建全局的ThreadLocal对象 def st1(): print('%s (in %s)'%(local_school.student, threading.current_thread(),name)) def st2(name): #绑定ThreadLocal的st1 local_school.st1=name st1() t1=threading.Thread(target=st2,args=('A1'),name='Thread-A') t2=threading.Thread(target=st2,args=('B1'),name='Thread-B') t1.start() t2.start() t1.join() t2.join()