7.2【多线程与多进程】线程间通信

该文章描述了一个Python程序,用于从YahooFinance下载多只股票的CSV数据,并通过多线程机制进行处理。程序采用下载线程(DownloadThread)进行IO操作,将数据放入线程安全的Queue,然后由一个转换线程(ConvertThread)进行CPU密集型的CSV到XML的转换。通过这种方式,程序利用了IO和CPU操作的并行性,提高了整体效率。
摘要由CSDN通过智能技术生成
http://table.finance.yahoo.com/table.csv?s=000001.sz
下载多只股票的csv数据,并将其转换为xml文件
由于GIL,多线程进行CPU密集型操作并不能提高执行效率,修改程序架构:
1.使用多个DownloadThread线程进行下载(IO操作)
2.使用一个ConverThread线程进行转换(CPU密集型操作)
3.下载线程把下载数据安全地传递给转换线程

import csv
from xml.etree.ElementTree import Element,ElementTree
import requests
from StringIO import StringIO
from xml_pretty import pretty
# 典型生产者与消费者模型
# 使用标准库中Queue.Queue,它是一个线程安全的队列

# from collections import deuqe
# q = deque() 
# Download线程把下载数据放入队列,Convert线程从队列里提取数据

from Queue import Queue
# 经常使用全局变量是一种不良的设计模式,通过构造器传入
class DownloadThread(Thread):
	def __init__(self, sid, queue):
		Thread.__init__(self)
		self.sid =sid
		self.url = 'http://table.finance.yahoo.com/table.csv?s=%s.sz'
		self.url %= str(sid).rjust(6, '0')
		self.queue = queue
		
	def download(self,url):
		response = requests.get(url, timeout=3)
		if response.ok:
			return StirngIO(response.content) 
	
	def run(self):
		print 'Download', self.sid
		#1.进行下载
		data = self.download(self.url)
		#2.将数据(sid, data)传递convert线程
		# # 多个线程访问q时,q是不安全的;对这里临界区代码加锁;或使用线程安全的队列
		# q.append(sid, data) # 在消费端pop出来
		self.queue.put((self.sid, data))

calss ConvertThread(Thread):
	def __init__(self, queue):
		Thread.__init__(self)
		self.queue = queue
	def csvToXml(self, scsv, fxml):
		reader = csv.reader(scsv) 
		headers = reader.next()
		headers = map(lambda h: h.replace(' ',''), headers)

		root = Element('Data') 
		for row in reader:
			eRow = Element('Row')
			root.append(eRow)
			for tag, text in zip(headers, row):
				e = Element(tag)
				e.text = text
				eRow.append(e)
		pretty(root)
		et = ElementTree(root)
		et.write(fxml)
	def run(self):
		# 接收传递过来的数据
		while True: # 只有1个消费者线程,需要循环处理多个生成者生成的数据
			sid, data = self.queue.get()
			print 'Convert', sid
			if sid == -1:
				break
			if data:
				fname = str(sid).rjust(6, '0') +'.xml'
				with open(fname, 'wb') as wf:
					self.csvToXml(data, wf)

if __name__ == '__main__':
	q = Queue()
	dThreads = [DownloadThread(i, q) for i in xrange(1, 11)]
	cThread = ConvertThread(q)
	for t in dThreads:
		t.start()
	cThread.start()
	for t in dThreads:
		t.join()
	q.put((-1,None))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值