3

我想用 C# 创建一个高性能服务器,它可能需要大约 10k 个客户端。现在我开始用 C# 编写一个 TcpServer 并为每个客户端连接打开一个新线程。我还使用一个线程来接受连接。到目前为止一切顺利,工作正常。

服务器必须反序列化 AMF 传入的对象做一些逻辑(比如保存玩家的位置)并发送一些对象回来(序列化对象)。我不担心序列化/反序列化部分 atm。

我主要担心的是,我将有很多带有 10k 客户端的线程,而且我在某个地方读到过,操作系统只能像几百个线程一样容纳。

是否有任何关于编写体面的异步线程服务器的资料/文章?还有其他可能性还是 10k 线程可以正常工作?我在谷歌上看过,但我找不到太多关于设计模式或清楚解释它的方式的信息

4

4 回答 4

4

你会遇到很多问题。

  1. 由于几个原因,您无法启动 10,000 个线程。它会破坏内核调度程序。如果您运行的是 32 位,那么 1MB 的默认堆栈地址空间意味着 10k 线程将保留大约 10GB 的地址空间。那会失败的。

  2. 您也不能使用简单的选择系统。本质上,对于套接字的数量,选择是 O(N)。使用 10k 个套接字,这很糟糕。

  3. 您可以使用 IO 完成端口。这是他们设计的场景。据我所知,没有稳定的托管 IO 完成端口库。您必须使用 P/Invoke 或托管 C++ 编写自己的代码。玩得开心。

于 2010-03-30T21:30:50.860 回答
3

编写高效的多线程服务器的方法是使用 I/O 完成端口(每个请求使用一个线程是非常低效的,正如@Marcelo 提到的那样)。

如果您使用 .NET 套接字类的异步版本,您可以免费获得它。请参阅此问题,其中包含指向文档的指针。

于 2010-03-30T21:32:17.980 回答
1

您绝对不希望每个请求都有一个线程。即使您的客户端较少,创建和销毁线程的开销也会削弱服务器,而且您不可能达到 10,000 个线程;操作系统调度程序将在那之前很久就死去。

网上有很多关于 C# 异步服务器编程的文章(例如,这里)。只是谷歌一下。

于 2010-03-30T21:25:26.837 回答
1

您想研究使用IO 完成端口。你基本上有一个线程池和一个 IO 操作队列。

I/O 完成端口为在多处理器系统上处理多个异步 I/O 请求提供了一个高效的线程模型。当一个进程创建一个 I/O 完成端口时,系统会为请求创建一个关联的队列对象,这些请求的唯一目的是为这些请求提供服务。处理许多并发异步 I/O 请求的进程可以通过将 I/O 完成端口与预先分配的线程池结合使用,而不是通过在接收 I/O 请求时创建线程来更快、更有效地完成此操作。

于 2010-03-30T21:31:33.060 回答