Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python gevent block redis';套接字请求_Python_Redis_Gevent - Fatal编程技术网

Python gevent block redis';套接字请求

Python gevent block redis';套接字请求,python,redis,gevent,Python,Redis,Gevent,目标:产生一些处理来自redis的数据pop(来自redis的pop,然后放入队列)的greenlet工作人员 运行环境:ubuntu 12.04 PYTHON版本:2.7 GEVENT版本:1.0 RC2 REDIS版本:2.6.5 REDIS-PY版本:2.7.1 from gevent import monkey; monkey.patch_all() import gevent from gevent.pool import Group from gevent.queue import

目标:产生一些处理来自redis的数据pop(来自redis的pop,然后放入队列)的greenlet工作人员

运行环境:ubuntu 12.04 PYTHON版本:2.7 GEVENT版本:1.0 RC2 REDIS版本:2.6.5 REDIS-PY版本:2.7.1

from gevent import monkey; monkey.patch_all()
import gevent
from gevent.pool import Group
from gevent.queue import JoinableQueue
import redis

tasks = JoinableQueue()
task_group = Group()

def crawler():
    while True:
        if not tasks.empty():
            print tasks.get()
            gevent.sleep()

task_group.spawn(crawler)
redis_client = redis.Redis()
data = redis_client.lpop('test') #<----------Block here
tasks.put(data)
来自gevent导入猴子的
;猴子
导入gevent
从gevent.pool导入组
从gevent.queue导入JoinableQueue
导入redis
任务=JoinableQueue()
任务组=组()
def crawler():
尽管如此:
如果不是任务,则为空()
打印任务。获取()
gevent.sleep()
任务组。繁殖(爬虫)
redis_client=redis.redis()

data=redis_client.lpop('test')#gevent提供了协作轻量级进程(而不是线程)。结果是,当您在某个地方有一个无限循环,并且调度器从未重新进入时,程序将阻止占用100%的CPU内核

在您的示例中,问题在于您定义爬虫循环的方式。显然,当任务为空时,有一个无限循环。而且由于gevent.sleep调用(将执行必要的屈服操作)仅在任务不为空时调用,这意味着永远不会重新进入调度程序

它似乎阻塞了lpop命令,因为Redis客户端延迟了连接。事件顺序如下:

  • 任务组已生成;但目前还没有绿色奥运的计划
  • redis_客户端已构建,但由于实际连接延迟,它尚未生成I/O
  • 称为lpop;这一次确实需要连接,因为Redis客户端必须等待连接和对lpop的回复;因此,它向调度器屈服
  • 调度程序激活爬虫工作程序
  • 无限循环,因为任务队列仍然为空
如果将gevent.sleep()放在循环本身中(在If之后),它会工作得更好,但它仍然是实现出列器的低效方法。这样会更好:

def crawler():
    while True:
        x = tasks.get()
        try:
            print "Crawler: ",x
        finally:
            tasks.task_done()

get()调用正在阻止工作进程,因此它将避免在队列为空时工作进程与调度程序之间进行乒乓游戏。

我不知道,但我仍然坚持我的答案;-)