首页 > Python > Python多线程同步
2015
03-17

Python多线程同步

Thread类的构造函数定义如下

group: 留作ThreadGroup扩展使用,一般没什么用
target:新线程的任务函数名
name:  线程名,一般也没什么用
args:  tuple参数
kwargs:dictionary参数

Thread类的成员变量和函数如下

start()         启动一个线程
run()           线程执行体,也是一般要重写的内容
join([timeout]) 等待线程结束
name            线程名
ident           线程ID
daemon          是否守护线程
isAlive()、is_alive()    线程是否存活
getName()、setName()     Name的get&set方法
isDaemon()、setDaemon()  daemon的get&set方法

这里的守护线程与Linux中的守护进程并不是一个概念。这里是指当所有守护线程退出后主程序才会退出,否则即使线程任务没有结束,只要不是守护线程,都会跟着主程序一起退出。而Linux中的守护进程定义正好相反,守护进程已经脱离父进程,不会随着父进程的结束而退出。

二、线程同步

线程同步是多线程中的一个核心问题,threading模块对线程同步有着良好的支持、包括线程特定数据、信号量、互斥锁、条件变量等。

1.线程特定数据

简而言之,线程特定数据就是线程独自持有的全局变量,相互之间的修改不会造成影响。

threading模块中使用local()方法生成一个线程独立对象,举例如下,其中sleep(1)是为了保证让子线程先运行完再运行接下来的语句。

2.互斥锁

threading中定义了两种锁:threading.Lock和threading.RLock。两者的不同在于后者是可重入锁,也就是说在一个线程内重复LOCK同一个锁不会发生死锁,这与POSIX中的PTHREAD_MUTEX_RECURSIVE也就是可递归锁的概念是相同的。

关于互斥锁的API很简单,只有三个函数————分配锁,上锁,解锁。

threading.Lock()        分配一个互斥锁
acquire([blocking=1])   上锁(阻塞或者非阻塞,非阻塞时相当于try_lock,通过返回False表示已经被其它线程锁住。)
release()               解锁
下面通过一个例子来说明互斥锁的使用。在之前的例子中,多线程print会造成混乱的输出,这里使用一个互斥锁,来保证每行一定只有一个输出。

输出如下:

其实上面这个程序是有问题的,我们想打印的是0~9,但实际上10也被打印了出来,原因很简单,因为两个线程交替打印,使得num在一个线程中可能加2,从而导致10被打印出来,所以必须在打印前再次check。

相信本文所述对大家的Python程序设计有一定的借鉴价值。

最后编辑:
作者:Jerry
一个积极向上的小青年,热衷于分享--Focus on DB,BI,ETL