Python中使用线程有两种方式:函数或者用类来包装线程对象。
1 函数式:调用thread模块中的start_new_thread()函数来产生新线程。
start_new_thread是实例化一个线程并运行的方法,方法的第一个参数接受一个线程运行时所执行的函数对象,第二个参数是方法执行时所需要的参数,以一个元组的形式传入。
import time
import thread
def timer(no, interval):
cnt = 0
while cnt<10:
print 'Thread:(%d)+ (%d)+ Time:%s\n'%(no,cnt,time.ctime())
time.sleep(interval)
cnt+=1
thread.exit_thread()
def test(): #Use thread.start_new_thread() to create 2 new threads
thread.start_new_thread(timer, (1,1))
thread.start_new_thread(timer, (2,2))
if __name__=='__main__':
test()
time.sleep(10)
最后已经不加的话会包异常:
Unhandled exception in thread started by
Error in sys.excepthook:
Original exception was:
所以不推荐使用thread,推荐使用threading
根据log显示,出现报错的现象:
启动线程之后,必须调用time.sleep休眠足够长的时间,使主线程等待所有子线程返回结果,如果主线程比子线程早结束,就会抛出这个异常。
2 创建threading.Thread的子类来包装一个线程对象,如下例:
#! /usr/bin/env python
#coding=utf-8
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();
'''
'''
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();
'''
class MyThread(threading.Thread):
def __init__(self,func,args,name):
super(MyThread,self).__init__();
self.func=func;
self.args=args;
self.name=name;
def run(self):
self.result=self.func(*self.args);
def getResult(self):
return self.result;
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=MyThread(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();
从上面可以看出MyThread继承了threading.Thread类,并在初始化方法中执行了必要的参数赋值。值得注意的是在Java类的继承中,如果不显示的指定调用父类的构造方法,那么默认将调用父类的无参构造方法。而在Python中,就不会主动去调用。所以这里需要显示的调用父类的初始化方法。
参考:
http://bestchenwu.iteye.com/blog/1063401
http://www.cnblogs.com/hbycool/articles/2749975.html