17 多线程和多进程并发
The modules described in this chapter provide support for concurrent execution of code. The appropriate choice of tool will depend on the task to be executed (CPU bound vs IO bound) and preferred style of development (event
driven cooperative multitasking vs preemptive multitasking).
17.1 threading --- 基于线程的并发
threading是一个基于_thread(python2中的thread)高级模块,和queue模块也有关系。在_thread模块缺失时可以使用dummy_threading模块。
在这个模块中定义了一些常用的方法:
threading.active_count() : 返回Thread对象的当前存活数。等同于enumerate()方法返回的list的长度
threading.current_thread() :返回当前Thread对象,和调用者的
threading.get_ident() : 返回 当前thread 标识,非0整数,没有意义。
threading.enumerate() : 返回一个包含所有存活的thread对象的list,不包括终止了的和没有启动的线程。
threading.main_thread() : 返回 main thread对象。
17.1.1 Thread-Local data
线程的私有数据,要管理thread-local数据,需要创建一个 local实例或者local的子类实例来保存属性。
mydata = threading.local()
mydata.x = 1
class threading.local
17.1.2 Thread Objects
Thread类表示在一个独立的线程里运行的任务,有两种方式定义这个任务:传递一个可调用的对象给生成器,或者在子类中重写run()方法,即不传递可调用对象,则执行类的run方法。
创建完成之后,调用start()方法来启动该线程,启动之后则认为线程是 alive的,除非run()方法终止或者抛出异常。
可以调用一个线程的join()方法,该方法会阻塞调用线程(主线程)直到被调用线程的join()方法停止。
线程可以有名字,可以在创建过程中传递,也可以通过name属性来读取和修改。
线程可以标识为 daemon线程,表示整个python程序退出之后,daemon线程仍保持。
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
该生成器应该带关键字参数调用,参数如下:
group: 为None,作为保留,后续ThreadGroup类被创建后扩展使用
target: 传递一个被run()方法调用的可调用对象。
name: 线程名字,默认是Thread-N
args: 是调用对象的参数,为元组对象(),只有一个参数时:(a,)
kwargs: 是一个关键字参数对象,默认是dict {}
daemon: 默认为None,如果为None则继承创建的线程的该属性。
start(): 启动线程任务
run(): 启动线程之后执行的任务,可以在子类中重写这个函数。
join(): 等待线程结束,calling线程一直阻塞直到调用的join()方法停止,或者超时,可以通过is_alive来判定是超时或者正常停止和异常退出。在start之前或者进入一个死循环会导致线程超时
getName()
setName()
ident(): 线程标识。
is_alive(): 确认线程是否存活
daemon: 布尔值,标识线程是否是一个daemon线程(True 是),必须在启动前设置该值。
isDaemon()
setDaemon()
17.1.3 Lock Objects
class threading.Lock
17.1.4 Rlock Objects
done