Python + Gevent + MultiProcessing:我的第一个程序非常简单的初学者问题

时间:2011-09-25 04:04:27

标签: python gevent

有人知道这段代码有什么问题吗?它只是“加载”永远。没有输出。 “网站”是几十个字符串的列表。

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

2 个答案:

答案 0 :(得分:11)

gevent.spawn()创建greenlets而不是进程(更多:所有greenlet在单个OS线程中运行)。因此multiprocessing.JoinableQueue不合适。

gevent基于协作多任务处理,即在您调用阻塞函数切换到gevent的事件循环之前,其他greenlet将无法运行。例如,下面的conn使用patched作为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()

答案 1 :(得分:3)

请改用gevent.queue.JoinableQueue。绿色线程(gevent内部使用它)既不是线程也不是进程,而是协同用户级调度。