我正在尝试在Python中实现一个FUSE驱动的文件系统,它提供来自本地和远程源的数据。文件系统由主FUSE线程处理:文件系统请求在请求时直接处理。
class MyFilesystem(Fuse):
def read(self, path, size, offset):
if self._isLocalFile(path):
return self._localRead(path, size, offset)
elif self._isRemoteFile(path):
# get file from server
# ...
我曾想过在初始化时创建第二个线程,这样可以保持客户端和服务器之间的通信畅通。命令以双向流动,因此客户端当前使用select()调用来等待任何传入命令。
class CommsClient(threading.Thread):
def run(self):
conn = self._connect()
while True:
r, w, e = select.select([conn], [], [], 1.0)
if conn in r:
self._handleData(conn)
# ...
我现在遇到的问题是连接两个线程。当文件系统线程处理请求时,它可能必须阻塞,直到通信线程返回来自服务器的回复。我认为实现这一目标的一种方法是将请求流/套接字从文件系统线程插入select()
调用,但我不确定套接字是否最适合用于线程间通信。我想,缩短select()
超时并检查事件或线程间变量也会起作用,但我希望机制尽可能快。
有谁知道处理这种情况的最佳方法?
答案 0 :(得分:2)
使用套接字进行线程间通信是完全可以接受的,但它比使用内存数据结构的线程和锁实现它要慢。 请注意,“较慢”是相对的:硬盘操作可能仍然会慢十倍。
虽然这不是问题的直接答案,但我建议你看看 ØMQ?它非常快,它为您提供了“套接字”,可以在各种传输中传输整个消息,如进程内,进程间,TCP和多播,并且它具有异步I / O.
答案 1 :(得分:1)
如果其他人从中受益,我最终使用的解决方案涉及使用threading.Event
锁定和非阻塞select()
调用:
class MyFilesystem(Fuse):
def read(self, path, size, offset):
if self._isLocalFile(path):
return self._localRead(path, size, offset)
elif self._isRemoteFile(path):
# get file from server
self.commsThread.requested_file = path
self.commsThread.done_event.clear()
self.commsThread.retrieved_file = None
self.commsThread.request_event.set()
self.commsThread.done_event.wait()
return self.commsThread.retrieved_file[offset:offset+size]
class CommsClient(threading.Thread):
def run(self):
conn = self._connect()
while True:
self.request_event.wait(0.1)
if self.request_event.is_set():
conn.request_file(self.requested_file)
r, w, e = select.select([conn], [], [], 0.0)
if conn in r:
self._handleData(conn)
if self.retrieved_file:
self.done_event.set()
# ...