我正在寻找一种在守护进程(Main
程序)和其他进程(机器人)之间进行有效通信的方法。这里的困难在于,我需要能够让机器人随时进出这条通信路径。
到目前为止,我使用Unix domain sockets
在进程之间进行通信。当我进行一对一的沟通时,这种方法运作良好。在我的新设置中,我不想依赖它们 - 可能是n
bots
queue.Queue
个{}发送数据,而且它们没有同步它们的传输。
逻辑上,我去了Queue
来解决这个问题。拥有一个main
bots
对象Queue
可以稳定拉出的对象正是我认为我需要的。
问题在于,我需要UDS
能够进出我的通信网络,所以我需要将Queue
传递给新注册的进程。
我尝试使用main
将Queue
分发到任何挂钩到accept()
的进程,但这不是一个选项,因为UDS
不可选。此外,class QueueDistributor(threading.Thread):
def __init__(self, q, addr, name='Queue Distributor'):
""" constructor, setting initial variables """
self._stopevent = threading.Event()
self.q = q
self.addr = addr
threading.Thread.__init__(self, name=name)
def run(self):
""" main control loop """
if os.path.exists(self.addr):
os.remove(self.addr)
sock = socket(AF_UNIX, SOCK_STREAM)
sock.settimeout(1)
sock.bind(self.addr)
sock.listen(1)
while not self._stopevent.isSet():
try:
client, addr = sock.accept()
try:
client.send(self.q)
except timeout:
continue
except Exception:
traceback.print_exc(file=sys.stdout)
except timeout:
continue
except Exception:
traceback.print_exc(file=sys.stdout)
sock.close()
def join(self, timeout=None):
""" Stop the thread. """
self._stopevent.set()
threading.Thread.join(self, timeout)
class Homer:
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null',
stderr='/dev/null'):
self.pidfile = pidfile
self.redirects = stdin, stdout, stderr
self.address = '/tmp/homer.uds'
self.running = False
self.q = Queue()
self.q_distributor = QueueDistributor(self.q, self.address)
# Open up file descriptors with zero buffering
self.trades = open('/tmp/trades.csv', 'ab', buffering=0)
self.tickers = open('/tmp/tickers.csv', 'ab', buffering=0)
self.books = open('/tmp/books.csv', 'ab', buffering=0)
# ...
def handle_data(self, data):
...
def run(self):
self.running = True
# Launch queue distribution Thread
self.q_distributor.start()
while self.running:
try:
data = self.q.get(timeout=0.1)
self.handle_data(data)
except Empty:
continue
except NotImplementedError as e:
log.error(e)
continue
# Shutdown Queue Distributor
self.q_distributor.join()
似乎也不适用于TCP
(这是有道理的,它是一个类似文件的全部)。
代码:
Queue
显而易见的替代方案是通过multiprocessing.connection.Listener
套接字接收数据,将其放入TCP
并从那里开始工作,但这是唯一的可能吗?
我见过engine.rootContext()->setContextProperty("SM", stateMachinePtr);
,但我认为这与自制Connections
解决方案大致相同,不是吗?