python-3.x - 具有 FIFO 的 Python 选择器运行到无限循环
问题描述
我正在尝试在我的 BSD 机器上使用 kqueue 编写一些非阻塞 FIFO 代码。这是小型服务器代码:server.py
import os
import selectors
sel = selectors.KqueueSelector()
TMP_PATH="/tmp/myfifo"
def fifo_read(fd, mask):
data = os.read(fd, 8)
print("fd:{} gives:{} \n", fd, data)
sel.unregister(fd)
print("unregistered")
def fifo_accept(listen_fd, mask):
print("accepted {}".format(listen_fd))
fd = os.dup(listen_fd)
print("duped to {}".format(fd))
sel.register(fd, selectors.EVENT_READ, fifo_read)
if __name__ == "__main__":
try:
os.unlink(TMP_PATH)
except:
pass
os.mkfifo(TMP_PATH)
listen_fd = os.open(TMP_PATH, os.O_RDONLY, mode=0o600)
sel.register(listen_fd, selectors.EVENT_READ, fifo_accept)
while True:
events = sel.select()
for key, mask in events:
cb = key.data
cb(key.fileobj, mask)
sel.close()
现在,当我运行时client.py
:
import os
TMP_PATH="/tmp/myfifo"
fd = os.open(TMP_PATH, os.O_WRONLY, mode=0o600)
res = os.write(fd, b"1234567")
print("sent {}".format(res))
当我运行客户端时,我得到:
sent 7
但在服务器上,它运行到无限循环。现在我明白了为什么会发生无限循环。我实际上尝试selectors
在此Python Docs 示例中模仿套接字的使用方式。这是我尝试过的:
- 我确实在没有复制的情况下尝试了代码
fd
,但它仍然处于无限循环中。 - 我尝试调用
sel.unregister
originallisten_fd
,但在这种情况下,第二次运行客户端不起作用(这是预期的)。
如果我遗漏了什么,谁能告诉我?
解决方案
所以我找到了解决这个问题的方法。使用套接字,我们在接受时获得一个新的套接字对象。所以我们需要通过调用unregister
original来模拟这种行为fileobj
,open
然后再次调用register
它。
固定代码:
import os
import selectors
sel = selectors.KqueueSelector()
try:
os.unlink("./myfifo")
except:
pass
os.mkfifo("./myfifo", 0o600)
def cb(fp):
sel.unregister(fp)
print(f"got {fp.read()}")
fp.close()
fp2 = open("./myfifo", "rb")
sel.register(fp2, selectors.EVENT_READ, cb)
if __name__ == "__main__":
orig_fp = open("./myfifo", "rb")
print("open done")
ev = sel.register(orig_fp, selectors.EVENT_READ, cb)
print(f"registration done for {ev}")
while True:
events = sel.select()
print(events)
for key, mask in events:
key.data(key.fileobj)
推荐阅读
- elasticsearch - 是否可以在 Elasticsearch 中结合 _msearch 和建议器?
- reactjs - 使用 Enzyme/Jest 测试 Ag Grid 但调用 ensureGridApiHasBeenSet 会导致测试失败
- reactjs - 更新由以下机构管理的视图的属性“lineCap”时出错:AIRMapPolyline in expo
- html - 在下面的这段代码中,我似乎无法将文本放在图像旁边
- assembly - 组装说明问题
- java - 从 JAR 运行时,无法在 Micronaut 应用程序中打开 Swagger UI
- r - 错误:`data` 和 `reference` 应该是具有相同级别的随机因素
- java - Vertx WebClient 使用太多文件描述符
- java - 在类路径资源中定义名称为“requestMappingHandlerMapping”的 bean 创建错误
- c++ - 有什么可以使静态布尔线程安全的吗?