gpt4 book ai didi

gevent - 为什么在这个例子中需要 gevent.sleep(0.1) 来防止应用程序阻塞?

转载 作者:行者123 更新时间:2023-12-04 15:01:16 25 4
gpt4 key购买 nike

我正在把我的头发拉到这个上面。我正在尝试使用 zeromq 和 gevent 获取最简单的示例。我将此脚本更改为使用 PUB/SUB 套接字,当我运行它时,“服务器”套接字将永远循环。如果我取消注释 gevent.sleep(0.1) 行,那么它会按预期工作并屈服于另一个绿色线程,在这种情况下是客户端。

问题是,为什么我必须手动添加 sleep 调用?我认为当我导入 zmq 的 zmq.green 版本时,发送和接收调用是非阻塞的,并且在下面进行任务切换。

换句话说,为什么我必须添加 gevent.sleep() 调用才能使这个示例工作?在 Jeff Lindsey 的原始示例中,他正在执行 REQ/REP 套接字,并且不需要添加 sleep 调用……但是当我将其更改为 PUB/SUB 时,我需要将其交给客户端进行处理。

#Notes: Code taken from slide: http://www.google.com/url?sa=t&rct=j&q=zeromq%20gevent&source=web&cd=27&ved=0CFsQFjAGOBQ&url=https%3A%2F%2Fraw.github.com%2Fstrangeloop%2F2011-slides%2Fmaster%2FLindsay-DistributedGeventZmq.pdf&ei=JoDNUO6OIePQiwK8noHQBg&usg=AFQjCNFa5g9ZliRVoN_yVH7aizU_fDMtfw&bvm=bv.1355325884,d.cGE
#Jeff Lindsey talk on gevent and zeromq

import gevent
from gevent import spawn
import zmq.green as zmq

context = zmq.Context()

def serve():
print 'server online'
socket = context.socket(zmq.PUB)
socket.bind("ipc:///tmp/jeff")
while True:
print 'send'
socket.send("World")
#gevent.sleep(0.1)

def client():
print 'client online'
socket = context.socket(zmq.SUB)
socket.connect("ipc:///tmp/jeff")
socket.setsockopt(zmq.SUBSCRIBE, '')
while True:
print 'recv'
message = socket.recv()


cl = spawn(client)
server = spawn(serve)

print 'joinall'
gevent.joinall([cl, server])


print 'end'

最佳答案

I thought when I import the zmq.green version of zmq that the send and receive calls are non blocking and underneath do the task switching.



zmq.green 仅在这些调用会阻塞时才会让步,如果它们准备好则不会让步(无需等待)。在你的情况下,发件人总是准备好,所以它永远没有理由让步。

一些提示:
  • 最小显式 yield 是 gevent.sleep(0) ,它不需要是有限的。
  • zmq.green 只产生阻塞调用。也就是说,如果套接字在您要求时始终准备好发送/接收,则它将永远不会让步。
  • socket.send仅在套接字未准备好发送时阻塞 ( not (socket.events & zmq.POLLOUT) ),
    对于 PUB 套接字来说,这实际上永远不会是真的(您将在 HWM 上看到它用于 PUSH、DEALER 等)。
  • 一般来说,不要相信发送到 yield , 由于 zeromq 的工作方式,除非出现这种情况,否则很少会出现这种情况
    您超出了配置的容量。
  • 与发送不同, recv 定期阻塞 在正常使用中,因此它会在大多数调用中产生。但是,如果对等方正在淹没您的传入缓冲区,则重复的 recv 调用将不会让步,直到没有准备好接收为止,因此您可能再次需要每隔一段时间显式地让步以防止饥饿。

  • zmq.green 相当于将发送/接收转换为:
    try:
    socket.send(msg, zmq.NOBLOCK) # or recv
    except zmq.ZMQError as e:
    if e.errno == zmq.EAGAIN:
    yield # and wait for socket to be ready, then try again

    因此,如果使用 NOBLOCK 发送/接收总是成功,则套接字永远不会产生。

    换句话说:如果套接字没有什么可等待的,它就不会等待。

    关于gevent - 为什么在这个例子中需要 gevent.sleep(0.1) 来防止应用程序阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13904114/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com