简体   繁体   English

了解多线程和执行过程

[英]Understanding Multithreading and execution process

I'm not clear on the process that CLR performs when running a program.我不清楚 CLR 在运行程序时执行的过程。 I'm not quite clear on when to use lock() or some other type of thread safe objects.我不太清楚何时使用 lock() 或其他类型的线程安全对象。

Please help me understand the following:请帮助我理解以下内容:

Having this code:有这个代码:

    public class Person {
        string Name {get;set;}
    }


public class Calc {
    public string DoStuff(Person p){
        // perform some processing on person object
        // maybe call external API and update person object
    }

}

Please correct me if I'm wrong but this is my understanding of Example 1. In single threaded app (suppose it's a mvc application and I'm using DI and already registered "Service" in the container.如果我错了,请纠正我,但这是我对示例 1 的理解。在单线程应用程序中(假设它是一个 mvc 应用程序,我正在使用 DI 并且已经在容器中注册了“服务”。

I call Service.Work() from somewhere in my application.我从应用程序的某个地方调用 Service.Work()。 new Calc() is created (CLR allocates this object in memory) and Calc.DoStuff() does computation on Person object. new Calc() 被创建(CLR 在内存中分配这个对象)并且 Calc.DoStuff() 对 Person 对象进行计算。 Since before the call new Calc() is created and get called from two browsers they are in separate execution paths.由于在调用 new Calc() 之前创建并从两个浏览器调用它们处于不同的执行路径中。 Is this correct?这样对吗?

// Example 1
public class Service {
    public void Work(person) {
       var calc = new Calc();
       string test = calc.DoStuff(person);
    }
}

// Example 2
public class Service {  
    public Service() {
        var calc = new Calc(); // this is different
    }   
    public void Work(person) {
        string test = calc.DoStuff(person);
    }
}

Now what happens in the same scenario, however this time at the time of allocating Service in memory Calc is instantiated in the Service's constructor.现在在相同的场景中会发生什么,但是这次在内存中分配服务时,Calc 是在服务的构造函数中实例化的。 Would that cause problems with to simultaneous calls to Work() (since there is only ONE instance of Calc? object.这是否会导致同时调用 Work() 出现问题(因为只有一个 Calc? 对象实例。

  • What happens then?那会发生什么? Would string name be populated with the "latest" string?).字符串名称是否会填充“最新”字符串?)。
  • Would lock be required here so that first it has to finish 1st calls request then second?这里是否需要锁定,以便首先完成第一个调用请求然后第二个?
  • What happens when two browsers call Work(Person) sending two instances of Person to that method.当两个浏览器调用 Work(Person) 向该方法发送两个 Person 实例时会发生什么。 Suppose Person objects goes "inside" Calc class and then an external API is called - and stalls for a bit.假设 Person 对象进入 Calc 类的“内部”,然后调用外部 API - 并暂停一段时间。 Then second request is called to Calc(Person) would this Person object be updated independently (even though there is only one instance of Calc()?).然后向 Calc(Person) 调用第二个请求,这个 Person 对象是否会被独立更新(即使只有一个 Calc() 实例?)。 Or would the first request (the one that stalled) be cancelled by the second and forgotten?或者第一个请求(停滞的那个)会被第二个取消并忘记吗?

Here is where your intuition went wrong:这是你的直觉出错的地方:

Now what happens in the same scenario, however this time at the time of allocating Service in memory Calc is instantiated in the Service's constructor.现在在相同的场景中会发生什么,但是这次在内存中分配服务时,Calc 是在服务的构造函数中实例化的。 Would that cause problems with to simultaneous calls to Work() (since there is only ONE instance of Calc? object.这是否会导致同时调用 Work() 出现问题(因为只有一个 Calc? 对象实例。

Each call to the Service function has its own thread stack, and thus separate copies of all local variables.对 Service 函数的每次调用都有自己的线程堆栈,因此所有局部变量的副本都是独立的。

For all intents and purposes, just picture the two browser requests as two totally separate programs.出于所有意图和目的,只需将两个浏览器请求描述为两个完全独立的程序。

一般来说,在这两种情况下,你不应该期望 Calc 的实例是单一的(singleton),所以你的 DoStuff 方法需要有某种同步,比如lock(p) ,例如,如果类 Person 的实例是相同的所有通话。

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

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