在本地和远程 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) 或同等强大的东西。用你的弱协议,可以证明竞争条件是无解的。
考虑以下 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) 或同等强大的东西。用你的弱协议,可以证明竞争条件是无解的。