许多线程或尽可能少的线程? [英] Many threads or as few threads as possible?

查看:126
本文介绍了许多线程或尽可能少的线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个副项目,我目前正在为一个古老的游戏编写一个服务器,我曾经玩过。我试图使服务器尽可能松耦合,但我想知道什么是一个良好的设计决策多线程。目前我有以下一系列操作:

As a side project I'm currently writing a server for an age-old game I used to play. I'm trying to make the server as loosely coupled as possible, but I am wondering what would be a good design decision for multithreading. Currently I have the following sequence of actions:


  • 启动(创建) - >

  • 服务器监听客户端,创建) - >

  • 客户端(监听命令并发送周期数据)

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

I'm assuming an average of 100 clients, as that was the max at any given time for the game. What would be the right decision as for threading of the whole thing? My current setup is as follows:


  • 在新服务器上侦听新连接的1个线程,在新连接上创建客户端对象并开始侦听

  • 客户端对象有一个线程,监听传入的命令并发送周期性数据。这是使用非阻塞套接字完成的,所以它只是检查是否有可用的数据,处理它,然后发送它排队的消息。

  • 游戏本身的一个线程(现在),因为我认为与整个客户端 - 服务器部分分离,在架构上

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

This would result in a total of 102 threads. I am even considering giving the client 2 threads, one for sending and one for receiving. If I do that, I can use blocking I/O on the receiver thread, which means that thread will be mostly idle in an average situation.

我主要关注的是,通过使用这么多的线程,我会囤积资源。我不担心竞争条件或死锁,因为这是我必须处理。

My main concern is that by using this many threads I'll be hogging resources. I'm not worried about race conditions or deadlocks, as that's something I'll have to deal with anyway.

我的设计是这样设置的,我<可以为所有客户端通信使用单个线程,无论是1还是100.我已经将通信逻辑与客户端对象本身分离,因此我可以实现它,而不必重写大量的代码。

My design is setup in such a way that I could use a single thread for all client communications, no matter if it's 1 or 100. I've separated the communications logic from the client object itself, so I could implement it without having to rewrite a lot of code.

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

The main question is: is it wrong to use over 200 threads in an application? Does it have advantages? I'm thinking about running this on a multi-core machine, would it take a lot of advantage of multiple cores like this?

谢谢!

的通常会被阻塞。我不希望连接超过5每分钟。来自客户端的命令很少出现,我平均每分钟20个。

Out of all these threads, most of them will be blocked usually. I don't expect connections to be over 5 per minute. Commands from the client will come in infrequently, I'd say 20 per minute on average.

按照我在这里得到的答案(上下文切换是我正在考虑的性能影响,但我不知道,直到你指出来,谢谢! )

Going by the answers I get here (the context switching was the performance hit I was thinking about, but I didn't know that until you pointed it out, thanks!) I think I'll go for the approach with one listener, one receiver, one sender, and some miscellaneous stuff ;-)

推荐答案

p>我写在.NET和我不知道如果我的代码的方式是由于.NET限制和他们的API设计,或者这是一个标准的做事方式,但这是我做了这种类型过去的事情:

  • A queue object that will be used for processing incoming data. This should be sync locked between the queuing thread and worker thread to avoid race conditions.


  • 将用于处理传入数据的队列对象。这应该在队列线程和工作线程之间同步锁定,以避免竞争条件。

A worker thread for processing data in the queue. The thread that queues up the data queue uses semaphore to notify this thread to process items in the queue. This thread will start itself before any of the other threads and contain a continuous loop that can run until it receives a shut down request. The first instruction in the loop is a flag to pause/continue/terminate processing. The flag will be initially set to pause so that the thread sits in an idle state (instead of looping continuously) while there is no processing to be done. The queuing thread will change the flag when there are items in the queue to be processed. This thread will then process a single item in the queue on each iteration of the loop. When the queue is empty it will set the flag back to pause so that on the next iteration of the loop it will wait until the queuing process notifies it that there is more work to be done.

用于处理队列中的数据的工作线程。将数据队列排队的线程使用信号量通知此线程处理队列中的项目。该线程将在任何其他线程之前启动,并且包含可以运行的连续循环,直到它接收到关闭请求。循环中的第一个指令是暂停/继续/终止处理的标志。该标志将被初始设置为暂停,使得线程处于空闲状态(而不是连续循环),同时没有要进行的处理。当队列中有要处理的项目时,排队线程将更改标志。然后,该线程将在循环的每次迭代中处理队列中的单个项目。当队列为空时,它将标志设置为暂停,以便在循环的下一次迭代中,它将等待,直到排队过程通知它有更多的工作要完成。

One connection listener thread which listens for incoming connection requests and passes these off to...

一个连接侦听器线程,它侦听传入的连接请求并将其传递给...

A connection processing thread that creates the connection/session. Having a separate thread from your connection listener thread means that you're reducing the potential for missed connection requests due to reduced resources while that thread is processing requests.

传入数据侦听器线程,侦听当前连接上的传入数据。所有数据被传递到排队线程以排队等待处理。

An incoming data listener thread that listens for incoming data on the current connection. All data is passed off to a queuing thread to be queued up for processing. Your listener threads should do as little as possible outside of basic listening and passing the data off for processing.

排队线程将右侧数据排队,顺序,所以一切都可以正确处理,这个线程提出信号量到处理队列,让它知道有数据要处理。将此线程与传入数据侦听器分离意味着您不太可能错过传入的数据。

A queuing thread that queues up the data in the right order so everything can be processed correctly, this thread raises the semaphore to the processing queue to let it know there's data to be processed. Having this thread separate from the incoming data listener means that you're less likely to miss incoming data.

某些会话对象在方法之间传递,

Some session object which is passed between methods so that each user's session is self contained throughout the threading model.

这样,线程就可以简单而稳健的模型我想出来了。我想找到一个比这更简单的模型,但我发现,如果我尝试和减少线程模型任何进一步,我开始缺少网络流上的数据或错过连接请求。

This keeps threads down to as simple but as robust a model as I've figured out. I would love to find a simpler model than this, but I've found that if I try and reduce the threading model any further, that I start missing data on the network stream or miss connection requests.

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

It also assists with TDD (Test Driven Development) such that each thread is processing a single task and is much easier to code tests for. Having hundreds of threads can quickly become a resource allocation nightmare, while having a single thread becomes a maintenance nightmare.

每个逻辑任务保持一个线程要简单得多,就像在TDD环境中为每个任务使用一个方法一样,你可以在逻辑上区分每个线程应该做什么。它更容易发现潜在的问题,更容易解决它们。

It's far simpler to keep one thread per logical task the same way you would have one method per task in a TDD environment and you can logically separate what each should be doing. It's easier to spot potential problems and far easier to fix them.

这篇关于许多线程或尽可能少的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆