多线程服务器,瓶颈问题
我正在开发一个多线程服务器,到目前为止效果很好 - 1 个单独的线程用于客户端接受,线程池用于数据读取和处理。今天我添加了新线程来执行一些操作并每 500 毫秒向客户端发送消息(仅 2-5 条消息)。我注意到速度明显下降,但我不确定为什么 - 它是单独的线程,而不是由于迭代和锁定集合,因为当我在 SendMessage 调用之前添加 // 时,它仍然像以前一样快。 SendMessage 基本上迭代所有连接的客户端,并为每个客户端调用 SendData 方法,该方法将数据写入其网络流。 我缺少什么?我仍然认为这些是不同的线程,我希望它不是由于stream.write.. 先感谢您!
I am developing a multithread server which works nice so far - 1 separate thread for client accepting, threadpool for data reading and processing. Today I have added new thread for doing some stuff and sending messages to client every 500 ms (just 2-5 messages). I have noticed quite massive slowdown but Im not sure why - its separate thread and its not due to iteration and locking collections, because when I add //before SendMessage call, it was still as fast as before.
The SendMessage basically iterates all connected clients and for each of them calls SendData method which writes data to their networkstream.
What am I missing? I still think those are different threads and I hope its not due to stream.write..
Thank you in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您可以尝试发布代码示例或摘要,那么您的消息发送实现将是一个不错的选择。
首先,纯粹是一般性建议。
现在是拿出分析器的好时机。这种猜测很诱人,而且通常是一种很好的心理练习,但是大多数时候,程序员对于他们认为导致软件速度变慢的原因是错误的。例如,探查器会告诉您,您的程序是否将 90% 的执行时间花费在一个方法中。
其次,推测性猜测。
听起来你的消息命令运行了一个计时器。确保您没有遇到重入问题 - 例如,如果您的 sendmessage 循环需要超过 500 毫秒才能完成(并且加上创建新线程和多个不可预测的延迟网络调用,它很可能会做到这一点),并且您拥有整个锁中的操作,那么计时器将继续生成位于该锁中等待上一个操作完成的线程池线程 - 并且可用线程池线程的数量是有限的。要检查这是否是一个问题,您甚至不需要分析器,当延迟变得很严重时,暂停调试器并检查当前正在执行的线程列表。
如果是这种情况,请考虑做其他事情 - 比如让一个线程在无限循环中运行,使用 waithandle 作为阻塞机制,并使用计时器每 500 毫秒设置一次 waithandle。
但如果您发布一些代码片段并运行分析器(Ants 或 DotTrace 都很好用),那么帮助您会容易得多。
If you can try to post a code sample or a summary, your message sending implementation would make a good candidate.
First, purely general advice.
This is a good time to whip out a profiler. This kind of guessing is tempting, and often a good mental excercise, but most of the time programmers are wrong about what they think is making their software slow. A profiler will tell you, for example, if your program is spending 90% of its execution time inside of one method.
Second, a speculative guess.
It sounds like your message command runs off a timer. Make sure that you aren't having issues with reentrancy - for example if your sendmessage loop takes longer than 500ms to complete (and together with creating a new thread and multiple unpredictable latency network calls it could well do that), and you have the whole operation in a lock, then the timer will keep spawning off threadpool threads that are sitting in that lock waiting for the previous operation to complete - and there is a finite number of available threadpool threads. To check if this is a problem you don't even need a profiler, when latency gets bad pause the debugger and check up on your list of currently executing threads.
If this is the case consider doing something else - like have a single thread that runs in an infinite loop using a waithandle as a blocking mechanism and timer that sets the waithandle every 500ms.
But it will be much easier to help you if you post some code snippets, and run a profiler (Ants or DotTrace both work great).
线程和用于套接字服务器之类的线程池是旧的处理方式。它非常不可扩展(最好不要有比核心更多的线程),并且充满了锁。
尝试将您的代码转换为异步代码。您只需要 1 个线程,只要输入到达或可以发送新数据,您就会收到回调。生成的代码速度更快,并且不存在这些瓶颈问题。
我知道这样的建议:不,不,重写你应该这样做的所有内容,并没有真正的帮助,因为它没有回答你提出的确切问题。但如果你有时间,我仍然认为这是一个很好的建议。否则,这对您要制作的下一个服务器来说是个好建议;^)
Threads & threadpools for things like socket servers is the old way to do things. It's very unscalable (optimally you would like to not have more threads than cores), and full of locks.
Try converting your code to asynchronous code. You only need 1 thread, and you get callbacks whenever input arrives or when new data can be sent. The resulting code is much faster and doesn't have these bottleneck problems.
I know the advice of: no no, rewrite everything you should do it like this, is not really helpful, since it doesn't answer the exact question you asked. But if you do have the time, I still think it's a good advice. Or else, it's good advice for the next server you'll make ;^)