一,GIL(全局解释器锁), 这个东西争议很大,至少我是不赞成的(屌丝反对无效). GIL的意思是任何时候只有一个CPU在运行, 也就是把你的多核机器变成一个单核机器. 好处是从根本上保证了线程安全, 坏处是使本来效率就很差的python变得更低效了.
1,print在多线程下打印可能会乱,尽量使用sys.stdout.write()
2,python的 error trace是分线程进行的,
3,一个线程挂掉并不会影响其他线程运行,即不会导致整个程序挂掉
二,thread 模块
thread是一个比较偏向底层的模块, 只提供了很少的功能:
1,start_new_thread(func, args, kwargs=None) 这个函数类似于C++中pthread_create, 就是开启一个线程并运行func函数, 其参数与apply完全一致
2,锁, allocate_lock(): 生成一个锁, 锁可以通过acquire()和release()加锁/解锁
3, thread不提供join和detach之类的东东
三, threading模块
threading更偏向应用, 提供了非常多的功能
1,启动线程, threading提供了三种方法启动一个线程:
a)创建一个Thread实例,传给它一个函数, 跟thread模块有点类似
b)创建一个thread实例,传给它一个可调用的类对象,即定义了__call__()的类, 有点像C++中的仿函数
c)从Thread派生一个子类,重载run()函数,再创建一个实例, 这种方法比较强大,较复杂的程序一般采用这种
2,Thread用start()开始, 可以用一个join()连接
3,threading提供条件判断condition,类似于C++中的pthread_cond_t
a)condition通过wait和notify进行通信
b)wait和notify必须被acquire和release包围,否则会报错
c)因为需要acquire,所以condition一次notify只能唤醒一个wait的线程, 这很可能与设计不符,因为:1,不能将所有wait的线程同时唤醒, 2,唤醒的事件要发生多次. 所以如果需要多个线程同时等待一个条件,请用event
4,threading提供了另一个条件判断event,可以支持多个线程同时等待一个条件
a)event通过wait和set进行通信
b)可以用clear进行清除
四,Queue模块
顾名思义,Queue是一个线程安全的队列, (都有GIL了,能不线程安全么)
1,使用put(item,block=0)加入元素 get(block=0) 取出元素, block!=0 表示将一直阻塞到可以get/put
2,提供辅助函数 qsize(): 返回队列大小, empty,()full()判空/满
五, multiprocessing模块(需要python2.6或以上)
想避开GIL? 想充分利用多核CPU? OK,总有办法的, 那就是用multiprocessing实现多进程
1,multiprocessing的API基本与threading模块一样, 会了threading基本就等于会了这个
2,避开GIL也就意味着没有免费的线程安全保证, 所以请用mutex保证线程安全
3,进程和线程总是有区别的, 但是大部分情况下不影响使用
4,如果真的很看重效率,最好还是用C++,python不擅长这个