简体   繁体   English

自定义多线程Http Server不是线程安全的

[英]Custom multi-threaded Http Server isn't a thread safe

There is a simple multi-threaded web server I wrote in C# (the part of the code): 我用C#(代码的一部分)编写了一个简单的多线程Web服务器:

  public class MyServer
    {
        private readonly HttpListener _listener = new HttpListener();
        private int  _dataId;
        public HttpServer(string prefix, string folder)
        {
            System.Threading.ThreadPool.SetMaxThreads(50, 1000);
            System.Threading.ThreadPool.SetMinThreads(50, 50);
            //........
        }

        public void Start()
        {
            _listener.Start();
            while (true)
             ThreadPool.QueueUserWorkItem(ProcessRequest, _listener.GetContext());
        }


        private void ProcessRequest(object obj)
        {
           //.....
        }


}

If a send the requests by browser (or whatever using only one main thread) then everything is OK. 如果通过浏览器(或仅使用一个主线程的任何一种)发送请求,则一切正常。 But if do it by the code below, then the server usually receives the same values for different requests: 但是,如果通过下面的代码执行此操作,则服务器通常会针对不同的请求接收相同的值:

Your thought? 你的想法?

-- EDIT --: - 编辑 -:

The simple question is, does using only local variables make me sure that my code is thread safe? 一个简单的问题是,仅使用局部变量是否可以确保我的代码是线程安全的? And vise versa: if I'm using instance variables (not static, that's _dataId in my case ), must I "look after" them to make them thread safe (for instance, by lock keyword)? 反之亦然:如果我使用实例变量(不是静态的, 在我的情况下为_dataId ),我是否必须“照看”它们以使它们成为线程安全的(例如,通过lock关键字)?

The canonical way to use the HttpListener in a multithreaded fashion would be through the Begin/End async pattern, here is an example . 以多线程方式使用HttpListener的规范方法是通过Begin / End异步模式, 这是一个示例

If your handler method is re-entrant, ie It does not depend on any instance state then chances are good that the code is thread-safe. 如果您的处理程序方法是可重入的,即它不依赖于任何实例状态,则代码很可能是线程安全的。 Question is whether any classes, methods etc. That you use are also thread-safe. 问题是是否有任何类,方法等。您使用的也是线程安全的。

You should start another thread, that will in cycle call GetContext, instead of queing the same context multiple time. 您应该启动另一个线程,该线程将循环调用GetContext,而不是多次查询同一个上下文。

public void Start()
{
    _listener.Start();
    ThreadPool.QueueUserWorkItem(StartImpl);
}
public void StartImpl()
{
    while (true)
        ProcessRequest(_listener.GetContext());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM