2011-09-25 97 views
4

任何人都知道这段代码有什么问题吗?它只是“加载”永远。没有输出。 “网站”是几十个字符串的列表。Python + Gevent + MultiProcessing:我的第一个程序很容易初学者问题

num_worker_threads = 30 

def mwRegisterWorker(): 
    while True: 
     try: 
      print q.get() 
     finally: 
      pass 

q = multiprocessing.JoinableQueue() 
for i in range(num_worker_threads): 
    gevent.spawn(mwRegisterWorker) 

for site in sites: 
    q.put(site) 

q.join() # block until all tasks are done 
+0

你可能更适合自己使用gevent并在不同的端口下运行python脚本的多个实例。一个简单的堆栈应该是:nginx(反向代理到运行python实例的多个端口) - > gevent wsgi python(在不同端口上运行的脚本的倍数)。也考虑gunicorn – scape

回答

10

gevent.spawn()创建greenlets不是过程(甚至更多:在一个单一的操作系统线程中运行的所有greenlets)。所以multiprocessing.JoinableQueue在这里不合适。

gevent基于合作多任务即,直到你调用切换到gevent的事件循环等greenlets将不会运行阻塞功能。例如下面的conn使用修补的gevent套接字方法来允许其他greenlet在等待来自站点的回复时运行。没有pool.join()放弃对运行事件循环的greenlet的控制,将不会进行连接。

要限制并发性,同时使请求到几个网站,你可以使用gevent.pool.Pool

#!/usr/bin/env python 
from gevent.pool import Pool 
from gevent import monkey; monkey.patch_socket() 
import httplib # now it can be used from multiple greenlets 

import logging 
info = logging.getLogger().info 

def process(site): 
    """Make HEAD request to the `site`.""" 
    conn = httplib.HTTPConnection(site) 
    try: 
     conn.request("HEAD", "/") 
     res = conn.getresponse() 
    except IOError, e: 
     info("error %s reason: %s" % (site, e)) 
    else: 
     info("%s %s %s" % (site, res.status, res.reason)) 
    finally: 
     conn.close() 

def main(): 
    logging.basicConfig(level=logging.INFO, format="%(asctime)s %(msg)s") 

    num_worker_threads = 2 
    pool = Pool(num_worker_threads)  
    sites = ["google.com", "bing.com", "duckduckgo.com", "stackoverflow.com"]*3 
    for site in sites: 
     pool.apply_async(process, args=(site,)) 
    pool.join() 

if __name__=="__main__": 
    main()