Python多线程/多进程代码

1 投票
4 回答
4498 浏览
提问于 2025-04-16 03:51

在下面的代码中,我在考虑使用多线程或多进程来从网址获取数据。我觉得使用线程池或进程池会比较理想,有谁能帮我建议一下解决方案吗?

我的想法是:用线程池或进程池来收集数据……我更倾向于使用进程而不是线程,但我不太确定。

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中的多进程

撰写回答