在本地和远程 GUI 之间同步

Synchronizing between a local and remote GUI

考虑以下 GUI:

当用户按下 + 按钮时,值增加到 6。

然而在另一台计算机上另一个用户是 运行 相同的 GUI。

两个 GUI 必须保持同步。 如果其中一位用户按下 + 按钮,则应该为两个 GUI 更新该值。

远程 GUI,即客户端,通过简单的协议与本地服务器通信。 通信采用从客户端发送的 cmd 和从服务器发送的响应的形式。有两个命令:

1. cmd:"GET_VALUE", response: "5"
2. cmd: "INCREMENT", response: "OK"

不幸的是,客户端必须轮询 GET_VALUE 才能收到通知, 但协议虽然有缺陷,但无法更改。

如何在 Qt、C++ 中实现它?

到目前为止,我已经想出了以下 类(粗略的轮廓):

class Model {
public:
    std::atomic<int> m_value;
};

class Widget : public QWidget {
public slots:
    void incrementClickedLocally(); // must update Model::m_value somehow
    void valueChangedFromModel(int value); // will update the QLineEdit
};

// Reads synchronously from TCP/IP using WinSocket and works on the Model 
class RemoteHandler : public QThread {
private:
    void run override();
};

我想使用 signals/slots 跨线程通信。 然而,似乎 RemoteHandler 不能使用 signal/slots 来获得 Model::m_value 因为插槽不能有 return 类型?

此外,从 Model 发出 valueChanged 信号以通知 Widget 会很方便。然而,为了做到这一点,模型必须是一个 QObject。 似乎当 Model 成为 QObject 时,我必须注意许多潜在的线程问题? 因为 Model 是线程安全的。因此,我可以直接从 RemoteHandler 中的非主线程请求 Model::m_value,而 Widget 可能同时从主线程访问同一个变量。

无法使用这些命令。

逻辑是 well-known 来自 multi-core CPU 的设计。您需要 Compare-and-Swap (CAS)、Load-Link/Store 条件 (LL/SC) 或同等强大的东西。用你的弱协议,可以证明竞争条件是无解的。