小试Python多线程

Python多线程相比其它语言实现起来要简单一点。最近做的工作是使用多线程将多个文件上传至新浪微盘。下面简要总结一下Python的多线程知识。

一、Python多线程知识

1. threading模块。
threading模块提供了各种非常好的同步机制,使用起来比较方便。threading的Thread类是我们比较常用的线程模块,可以从这个Thread类中派生出一个子类,创建这个子类的实例,然后调用它的start()方法,来开始线程的执行。在这个子类中,我们需要重写run方法,让这个子类完成我们需要的功能。

2. Queue模块
Queue模块可以用来进行线程间通讯,让各个线程之间共享数据。
1). 可使用put(item, block=0)方法向队列中放置item,如果block=False,则将item放置到队列中并且不阻塞,如果队列是满的,则立即抛出异常。如果block参数不为0,且带有timeout参数,并且timeout是正数,则put阻塞timeout所指定的时间,如果队列还是满的,则抛出Full异常。
2). 可使用get()方法来从队列中取出数据,它也有block参数和timeout参数,这两个参数和put方法中的参数类似,如果队列空的情况下get参数,则可能会抛出Empty Exception。从Python手册的信息上来看,get和put方法是线程安全的。
3).Queue的empty和full方法可以用来判断队列是否为空和满。如果队列为空则empty返回True,如果队列满则Full返回True。

二、Python多线程使用举例

下面给出我写的关于使用Python多线程向新浪微盘上传文件的代码
1).线程管理类,它向队列分配任务,并启动多线程。这里,我往queue队列中放置了一个列表,存放在线程中需要使用的数据。并建立了一个thread列表,存放指定数目的线程,然后将线程启动执行。Queue的join方法会阻塞等待所有线程执行完毕。
class UploadThreadHandler():
	def __init__(self, list_widget, cloud_path, access_token, thread_num=5):
		self.access_token = access_token
		self.threads = []
		count = list_widget.count()
		self.m_queue = Queue.Queue(count)
		if count == 0:
			return
		for i in range(count):  # 初始化队列
			self.m_queue.put((list_widget.item(i), cloud_path, list_widget))
		for i in range(thread_num):  # 初始化线程池
			self.threads.append(UploadThread(self.m_queue, self.access_token))
			self.threads[i].setName("i")
			self.threads[i].start()

	def wait_complete(self):
		self.m_queue.join()
2).线程类,线程类的代码如下所示,在run方法中,while循环不断从queue中取出列表信息,然后根据列表信息,来执行文件的上传工作。若队列已空,则get抛出异常,从而导致线程结束。其余代码,可忽略。
class UploadThread(threading.Thread):
	def __init__(self, queue, access_token):
		"""path 是本地的路径"""
		threading.Thread.__init__(self)
		self.m_queue = queue
		self.access_token = access_token
		self.client = client(self.access_token)
		self.exitFlag = False

	def run(self):
		"""上传文件"""
		print "start upload thread"
		while self.exitFlag is not True:
			if self.m_queue.empty():
				break
			try:
				item, cloud_path, list_widget = self.m_queue.get()
				if (item.text() == QtCore.QString("成功上传...".decode("utf-8"))):
					continue
				sha1 = Util.q_string2str(item.text())
				sha1 = sha1[sha1.rindex("\\") + 1:]
				result, is_success = self.client.files_put(cloud_path + sha1, item.text())
				print result, is_success
				if is_success:
					params = {"name": sha1, "option": "fragmentation"}
					url = ConfigUtil.read_ops("config.config", "server_address", "address") + \
						ConfigUtil.read_ops("config.config", "sub_address", "upload_state")
					netutil.sendPost(url, params)
					result = JsonUtil.str2json(result)
					if "error" in result.keys():
						continue
					print "成功上传文件" + cloud_path + sha1
					item.setText("成功上传...".decode("utf-8"))
			except Exception, e:
				print Exception, e
				break
			finally:
				self.m_queue.task_done()
		print "upload thread end"

以上代码测试了几次暂时没有发现什么错误,可以利用多线程多连接向新浪微盘同时上传多个文件,比较快的。若连接开多了则新浪微盘会拒绝连接的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值