Python多线程/多进程代码
在下面的代码中,我在考虑使用多线程或多进程来从网址获取数据。我觉得使用线程池或进程池会比较理想,有谁能帮我建议一下解决方案吗?
我的想法是:用线程池或进程池来收集数据……我更倾向于使用进程而不是线程,但我不太确定。
import urllib
URL = "http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sl1t1v&e=.csv"
symbols = ('GGP', 'JPM', 'AIG', 'AMZN','GGP', 'JPM', 'AIG', 'AMZN')
#symbols = ('GGP')
def fetch_quote(symbols):
url = URL % '+'.join(symbols)
fp = urllib.urlopen(url)
try:
data = fp.read()
finally:
fp.close()
return data
def main():
data_fp = fetch_quote(symbols)
# print data_fp
if __name__ =='__main__':
main()
4 个回答
0
其实你可以不需要这两者就能做到。你可以通过异步调用在一个线程中完成,比如使用 twisted.web.client.getPage
这个来自 Twisted Web 的方法。
1
这里有一个非常简单的例子。它会一个一个地遍历符号,然后把每个符号传递给fetch_quote这个函数。
import urllib
import multiprocessing
URL = "http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sl1t1v&e=.csv"
symbols = ('GGP', 'JPM', 'AIG', 'AMZN','GGP', 'JPM', 'AIG', 'AMZN')
#symbols = ('GGP')
def fetch_quote(symbol):
url = URL % '+'.join(symbol)
fp = urllib.urlopen(url)
try:
data = fp.read()
finally:
fp.close()
return data
def main():
PROCESSES = 4
print 'Creating pool with %d processes\n' % PROCESSES
pool = multiprocessing.Pool(PROCESSES)
print 'pool = %s' % pool
print
results = [pool.apply_async(fetch_quote, sym) for sym in symbols]
print 'Ordered results using pool.apply_async():'
for r in results:
print '\t', r.get()
pool.close()
pool.join()
if __name__ =='__main__':
main()
1
你有一个程序需要一次性请求多个信息。我们来试着一个一个地获取这些信息。你的代码是:
def fetch_quote(symbols):
url = URL % '+'.join(symbols)
fp = urllib.urlopen(url)
try:
data = fp.read()
finally:
fp.close()
return data
def main():
for symbol in symbols:
data_fp = fetch_quote((symbol,))
print data_fp
if __name__ == "__main__":
main()
所以在main()函数中,会一个接一个地调用每个网址来获取数据。
现在我们用一个进程池来实现多进程处理:
import urllib
from multiprocessing import Pool
URL = "http://download.finance.yahoo.com/d/quotes.csv?s=%s&f=sl1t1v&e=.csv"
symbols = ('GGP', 'JPM', 'AIG', 'AMZN','GGP', 'JPM', 'AIG', 'AMZN')
def fetch_quote(symbols):
url = URL % '+'.join(symbols)
fp = urllib.urlopen(url)
try:
data = fp.read()
finally:
fp.close()
return data
def main():
for symbol in symbols:
data_fp = fetch_quote((symbol,))
print data_fp
if __name__ =='__main__':
pool = Pool(processes=5)
for symbol in symbols:
result = pool.apply_async(fetch_quote, [(symbol,)])
print result.get(timeout=1)
在下面的main函数中,会为每个符号的网址创建一个新的进程来请求数据。
注意:在Python中,由于存在全局解释器锁(GIL),多线程通常被认为不是一个好的解决方案。
想了解更多,可以查看文档:Python中的多进程