多线程 – 很多线程或尽可能少的线程?

前端之家收集整理的这篇文章主要介绍了多线程 – 很多线程或尽可能少的线程?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
作为一个侧面项目,我正在为一个我曾经玩过的古老游戏编写一个服务器.我试图使服务器尽可能松散耦合,但我想知道什么是多线程的一个很好的设计决定.目前我有以下操作顺序:

>启动(创建) – >
>服务器(监听客户端,创建) – >
>客户端(监听命令并发送周期数据)

我假设平均有100个客户,因为这是游戏在任何给定时间的最大值.对于整个事情的线索是什么正确的决定?我目前的设置如下:

侦听新连接的服务器上的1个线程,在新连接上创建客户端对象并再次开始侦听.
>客户端对象有一个线程,监听传入命令和发送周期性数据.这是使用非阻塞套接字完成的,因此只需检查是否有数据可用,处理该数据,然后发送已排队的消息.在发送接收周期开始之前完成登录.
>一个线程(现在)为游戏本身,因为我认为是与整个客户端 – 服务器部分分开,在架构上说.

这将导致总共102个线程.我甚至考虑给客户端2个线程,一个用于发送,一个用于接收.如果我这样做,我可以在接收器线程上使用阻塞I / O,这意味着线程在平均情况下大部分空闲.

我的主要关注点是,通过使用这个很多线程,我将占用资源.我不担心种族条件或僵局,因为这是我必须处理的事情.

我的设计是这样设置的,我可以使用一个线程进行所有的客户端通信,无论是1或100.我把通信逻辑与客户端对象本身分开了,所以我可以实现它,而不必重写很多代码.

主要的问题是:在应用程序中使用超过200个线程是错误的吗?有优势吗我正在考虑在多核机器上运行这个功能,是否需要像这样的多个内核的很多优势?

谢谢!

在所有这些线程中,大多数线程通常会被阻塞.我不期望连接每分钟超过5次.客户的命令很少出现,平均每分钟20分钟.

按照我在这里的答案(上下文切换是我正在考虑的性能,但我不知道,直到你指出了,谢谢!)我想我会去一个听众,一个接收者,一个发件人和一些杂项的东西;-)

解决方法

我写在.NET中,我不知道我的代码是由于.NET限制和API设计的,或者这是一个标准的做事方式,但是我是如何做这样的事情过去:

>将用于处理传入数据的队列对象.这应该在排队线程和工作线程之间同步锁定,以避免竞争条件.
>用于处理队列中的数据的工作线程.队列数据队列的线程使用信号量来通知此线程来处理队列中的项目.该线程将在任何其他线程之前自动启动,并包含可以运行的连续循环,直到它收到关闭请求.循环中的第一条指令是暂停/继续/终止处理的标志.标志将初始设置为暂停,以便线程处于空闲状态(而不是连续循环),而不需要处理.当队列中有要处理的项目时,排队线程将更改标志.然后,该线程将在循环的每次迭代中处理队列中的单个项目.当队列为空时,它会将标志设置为暂停,以便在循环的下一次迭代时,它将等到排队过程通知有更多的工作要完成.
>一个连接监听器线程,用于监听传入的连接请求并将其传递给…
>创建连接/会话的连接处理线程.从连接侦听器线程中单独的线程意味着您正在减少由于资源减少而丢失的连接请求的潜力,而该线程正在处理请求.
>传入数据监听器线程,用于侦听当前连接上的传入数据.所有数据都被传递到排队等待线程处理.您的侦听线程应尽可能少地进行基本侦听之外,并将数据传送出去处理.
>排队线程以正确的顺序排列数据,以便正确处理所有内容,该线程将信号量提升到处理队列,以便知道要处理的数据.让线程与传入的数据监听器分开意味着您不太可能错过传入的数据.
>在方法之间传递的一些会话对象,以便每个用户的会话在整个线程模型中都是自包含的.

这使得线程可以像我已经想到的那样简单但是可靠的模型.我想找到一个比这更简单的模型,但是我发现,如果我尝试减少线程模型,我开始丢失网络流中的数据或错过连接请求.

它还协助TDD(测试驱动开发),使得每个线程正在处理单个任务,并且更容易进行代码测试.拥有数百个线程可以迅速成为资源分配的噩梦,而单线程成为维护噩梦.

每个逻辑任务保持一个线程与在TDD环境中每个任务拥有一个方法相同的方式要简单得多,您可以在逻辑上分离每个应该做的事情.发现潜在的问题更容易,更容易解决它们.

猜你在找的Java相关文章