我在嵌入式 Linux 环境中使用 C++ 和 Qt,最近我们的项目更新为使用多个进程,一个作为“服务器”,另一个作为“客户端”。为了处理进程之间的通信,负责更新的团队实施了 Thrift。
Qt 有自己的 IPC 处理,例如 Remote Objects 系统,或者甚至只是一个简单的 QLocalServer,它在 QDataStream 的帮助下发送和接收序列化的 Qt 对象。
他们选择Thrift是因为他们不想把项目重写成异步的,而Thrift提供了同步通信(例如返回值或副作用处理)。为了避免死锁,我们的“服务器”和“客户端”都有一个额外的线程运行来处理传入的 Thrift 请求,它可以选择将工作发送到主线程并等待它完成后再回复请求。
我想改用 Remote Objects 系统,因为它似乎可以消除很多开销和复杂的设置,但 Remote Objects 并不打算同步使用。
这似乎不是一个合适的替代品,但是可以吗?最终目标是有时能够从副本同步调用对象上的槽,同时避免死锁。如果一个进程同步调用一个槽,而这个槽又试图在另一个进程上同步调用一个槽,就会发生死锁。我知道这两种解决方案都不“正确”,但我正在尝试使用我得到的东西。
我有一个原型,它在线程内部创建
QRemoteObjectHost
并使用该线程的事件循环来处理处理。然后,在主线程上,我创建了我的 Source 对象。当它们准备就绪时,我调用 moveToThread()
将它们推送到上述线程,然后使用 postEvent()
将自定义事件发布到该线程的事件循环,这将使用 Source 对象在远程主机上调用 enableRemoting()
。
这行得通,即使我用
while
循环阻塞了主线程以模拟冗长的处理,我的客户端也可以连接并接收其副本的信息。
缺点是 Source 对象现在位于另一个线程中,这违背了大部分目的:从主线程正常使用我的对象的能力。现在我不得不担心我的来源有不同的线程亲和力。
有没有更好的方法来完成这个?