所以上一个例子的工作原理就是在启动线程的时候,给每个线程都加了一把锁,直到线程运行介绍,再释放这个锁。同时在Python的main线程中用一个while循环来不停的判断每个线程锁已释放。这个方法虽然避免了最开始的例子中人为的时间控制,但是还不方便,高效。
所以在较新的Python版本中,都推荐使用threading模块。
看下threading模块的API,有过JAVA开发经验的会发现它和java.lang.Thread类非常接近。这里需要说的一点就是threading的run方法可以返回函数值,这点在用于跟踪和判断线程运行正常与否非常有作用。
threading模块支持三种方法来创建线程。而前两种方式都与其Thread类有关。看下它的简要说明:
class Thread(_Verbose) : __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None)
其中target指的是一个具体的函数,或者可调用的类实例(这里指实现了__call__方法的类实例)
第一种方法:指定线程运行的时候调用的函数。举例如下:
from time import ctime,sleep
import threading;
from random import choice
def loop(number,sec):
print "Thread ",number," begins and will sleep ",sec," at ",ctime();
sleep(sec);
print "Thread ",number,"ends at ",ctime();
def main():
seconds=[2,4];
threads=[];
array=range(len(seconds));
for i in array :
t=threading.Thread(target=loop,args=(i,choice(seconds)));
threads.append(t);
print "main Thread begins at ",ctime();
for t in threads :
t.start();
for t in threads :
t.join();
print "main Thread ends at ",ctime();
if __name__=="__main__" :
main();
这里target指向了一个具体的函数对象,而args传入了该方法调用时所必须的参数。这里传入了一个随即的睡眠时间。其中thread.join表示要等待该线程终止,和java中的Thread.join(long millionseconds)作用一样,如果不指定具体的时间的话,将会一直等待下去。
第二种方法就是指定一个可调用的类实例,实际上与前面一种非常的接近。如下所示:
from time import ctime,sleep
import threading;
from random import choice
class ThreadFunc(object):
def __init__(self,func,args,name):
self.func=func;
self.args=args;
self.name=name;
def __call__(self):
self.func(*self.args);
def loop(number,sec):
print "Thread ",number," begins and will sleep ",sec," at ",ctime();
sleep(sec);
print "Thread ",number,"ends at ",ctime();
def main():
seconds=[2,4];
threads=[];
array=range(len(seconds));
for i in array :
t=threading.Thread(target=ThreadFunc(loop,(i,choice(seconds)),loop.__name__));
threads.append(t);
print "main Thread begins at ",ctime();
for t in threads :
t.start();
for t in threads :
t.join();
print "main Thread ends at ",ctime();
if __name__=="__main__" :
main();










