【发布时间】:2017-11-08 00:36:36
【问题描述】:
我正在开发一个连接到不同服务器、收集数据并显示它的应用程序。 实际上,我已经创建了它,但感觉我把它弄错了,因为它创建了一堆线程,而且我明白它是不可扩展的。
现在我有以下逻辑(简化的 c++ 伪代码):
// handles one connection
class Client
{
public:
void start(); //opens socket, connects, starts threads
void stop(); //closes socket, joins threads
ClientState getState();
void requestState();
private:
thread _threadReceive; // runs "handleReceive()" in a loop
thread _threadSend; // runs "handleSend()" in a loop
thread _threadUpdate; // runs "update()" in a loop
queue _commands;
queue _replies;
ClientState _currentState;
void handleReceive(); // recv reply from server, push to "_replies"
void handleSend(); // pops from "_commands", send to server
void update(); // pops reply, processes it, updates current state
//...
};
然后我有以下内容:
//App's logic
class App
{
public:
void start(); // init app, creates clients from config
void stop(); // iterates over "_clients" and calls "stop()", joins threads
private:
vector<Client> _clients;
vector<ClientState> _clientStates;
thread _threadUpdateClients;
thread _threadRequestClients;
void connect(); //iterate over "_clients" and "start()";
void updateStates(); //iterate over "_clients" and fill "_clientStates" accordingly
void requestStates(); //iterate over "_clients" and call "requestState()"
void updateUi(); // iterate over "_clientStates" and display them
//...
}
显然,这意味着要使用大量锁定和各种丑陋的代码来同步所有内容(这会导致上下文切换)。最令人沮丧的部分是它可以工作并且在成功的应用程序中成长。
此代码是我几年前编写的 .NET 4.5 C# 代码(这是我的第一个实际多线程应用程序)的直接移植 - 我需要在几台 Windows 2000 和 XP SP1 机器上执行它。 我“感觉到”了所有问题,但我不知道如何以适当的方式实施它。有很多简单的客户端-服务器教程,但我从来没有发现任何关于模式/架构、程序结构的东西。我也阅读了很多关于 select() 和非阻塞套接字的内容,但我真的很困惑:
- 如何正确使用select()?
- 如何使用非阻塞套接字组织状态/数据存储、队列等。
- 它在 Windows XP 上是否可用,因为我在使用 MSDN 指南时遇到了各种问题(一些 winsock 功能在 2000、XP、Vista 上不可用)。
我阅读了有关 asio、libev 实现的信息,但它们隐藏了细节,最终我缺乏知识正是导致我陷入这种情况的原因。 现在我只是简单地迭代和更新所有活动的连接,收集数据并显示,但我总觉得这不是一个正确的实现。
【问题讨论】:
-
互联网上有 吨 的网络教程,其中许多包括使用 Windows 套接字 API(这与“标准”POSIX API)。最好的当然包括如何使用
select。 -
此外,虽然您绝对应该了解套接字和网络如何在较低级别上工作,但一旦您学会了废弃代码并转向更高级别的 API 或框架。从长远来看,使用高级框架了解幕后发生的事情是一件好事(而且 IMO 是强制性的)可以让程序员的生活变得更加轻松。
-
这个问题跑题了。询问架构的更好地方是Software Engineering。
-
@IInspectable 在引用其他网站时,指出cross-posting is frowned upon 通常会有所帮助