python多线程编程(二)--threading模块

上一篇文章讲thread模块的使用,我们接下来看threading模块怎么使用。

threading模块对象

对象

描述

Thread

一个线程的执行对象

Lock

锁对象

RLock

可重入锁对象,使单线程可以再次获得已经获得了的锁(递归锁定)

Condition

条件变量,让一个线程停下来,等待其它线程满足了某个条件

Event

事件对象,通用的条件变量

Semaphore

信号量

BoundedSemaphore

Semaphore类似,只是它不允许超过初始值

Timer

Thread相似,不过它要等待一段时间才开始运行

threadingThread类是最主要的运行对象。

Thread对象的函数

函数

描述

start()

线程开始执行

run()

线程功能函数

join(timeout=None)

程序挂起,直到线程结束;如果给了timeout,则最多阻塞timeout

getName()

返回线程名字

setName(name)

设置线程名字

isAlive()

这个线程是否还在执行

isDaemon()

返回线程的daemon标志

setDaemon(daemonic)

设置线程的daemon属性,一定要在调用start()函数前调用

使用Thread类,我们介绍三种方法来创建线程。

●       创建一个Thread的实例,传给它一个函数

●       创建一个Thread的实例,传给它一个可调用的类对象

●       Thread派生出一个子类,创建一个这个子类的实例

下面看第一种,创建一个Thread的实例,传给它一个函数

我们将初始化一个Thread对象,把函数(及其参数)传进去。这种方式实例化一个Thread与调用thread.start_new_thread()之间的最大区别就是,新线程不会立即开始。当你创建线程对象又不想立即开始执行的时候,这是很有用的。

#coding: utf-8
import threading
from time import sleep, ctime

loops = [4,2]

def  loop(nloop, nsec):
	print ‘loop‘, nloop, ‘start at:‘, ctime()
	print ‘loop %d 挂起%d秒‘ % (nloop, nsec)
	sleep(nsec)
	print ‘loop‘, nloop, ‘done at:‘, ctime()

def main():
	print ‘main thread start!‘
	threads = []  #线程列表
	nloops = range(len(loops))

	for i in nloops:
		t = threading.Thread(target=loop, args=(i, loops[i]))
		threads.append(t)

	for i in nloops:
		threads[i].start()

	for i in nloops:
		threads[i].join()  #等待线程结束

	print ‘all done at:‘, ctime()

if __name__ == ‘__main__‘:
	main()

运行结果:

python多线程编程(二)--threading模块

这种方式就省了管理一堆锁的功夫了,只要对每个线程调用join()函数,就会等到线程结束。

另外,如果你的主线程除了等线程结束外,还有其它的事情要做(如处理或等待其它的客户请求),那就不用调用join()。一旦线程启动后,就会一直运行,直到线程的函数结束,退出为止。所以只有在你要等待线程结束的时候才要调用join()

第二种方式,创建一个Thread的实例,传给它一个可调用的类对象

这种方式就是在第一种方式的情况下,将函数封装进类对象里面,由类对象提供功能函数。在创建Thread对象时会实例化这个类对象。

#coding: utf-8
import threading
from time import sleep, ctime

loops = [4,2]

class Func(object):
	def __init__(self, func, args, name=""):
		self.name = name
		self.func = func
		self.args =args

	def __call__(self):
		self.res = self.func(*self.args)  #如果python版本是1.6以下,就使用apply(self.func, self.args)

def  loop(nloop, nsec):
	print ‘loop‘, nloop, ‘start at:‘, ctime()
	print ‘loop %d 挂起%d秒‘ % (nloop, nsec)
	sleep(nsec)
	print ‘loop‘, nloop, ‘done at:‘, ctime()

def main():
	print ‘main thread start!‘
	threads = []  #线程列表
	nloops = range(len(loops))

	for i in nloops:
		t = threading.Thread(target=Func(loop, (i, loops[i]), loop.__name__))
		threads.append(t)

	for i in nloops:
		threads[i].start()

	for i in nloops:
		threads[i].join()  #等待线程结束

	print ‘all done at:‘, ctime()

if __name__ == ‘__main__‘:
	main()

创建新线程的时候,Thread对象会调用我们的Func对象,这时会用到一个特殊函数__call__()这是python的一个特性,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。比如实现了__call__函数的Func对象实例instance,形如instance(arg1,arg2,...)实际上调用的就是instance.__call__(arg1,arg2,...)

第三种方式,Thread派生出一个子类,创建这个子类的实例

#coding: utf-8
import threading
from time import sleep, ctime

loops = [4,2]

class MyThread(threading.Thread):
	def __init__(self, func, args, name=""):
		threading.Thread.__init__(self)
		self.name = name
		self.func = func
		self.args =args

	def run(self):
		self.res = self.func(*self.args)
		
def  loop(nloop, nsec):
	print ‘loop‘, nloop, ‘start at:‘, ctime()
	print ‘loop %d 挂起%d秒‘ % (nloop, nsec)
	sleep(nsec)
	print ‘loop‘, nloop, ‘done at:‘, ctime()

def main():
	print ‘main thread start!‘
	threads = []
	nloops = range(len(loops))

	for i in nloops:
		t = MyThread(loop, (i, loops[i]), loop.__name__)
		threads.append(t)

	for i in nloops:
		threads[i].start()

	for i in nloops:
		threads[i].join()

	print ‘all done at:‘, ctime()

if __name__ == ‘__main__‘:
	main()

这种方式使创建线程对象的代码更简洁。


python多线程编程(二)--threading模块,布布扣,bubuko.com

python多线程编程(二)--threading模块

上一篇:java-选择排序法


下一篇:Java函数式编程(四)集合的使用