我一直在开发多线程算法,我对C#中的线程之间共享类成员存在一些疑问。C#:在线程之间共享类成员
我们假设我们有两个类Algorithm和Processor。处理器有一个 主要方法DoWork和其他可用资源方法偶尔调用以更改可用资源的数量进行处理。 方法运行和UpdateResources在算法对象由两个不同的线程调用,可能在不同核心上的工作。
是否有可能是_processor变量将被存储在CPU的缓存,绝不会被上传到内存中,并AvaliableResources将永远不会被调用,因为_processor是空的第二个线程?
class Processor
{
public void DoWork() { ... }
public void AvaliableResources(int x) { ... }
}
class Algorithm
{
private Processor _processor;
public void Run()
{
_processor = new Processor();
_processor.DoWork();
_processor = null;
}
public void UpdateResources(int x)
{
_processor?.AvaliableResources(x);
}
}
如果有一个同步的问题将下面的代码是为它的解决方案?
替代1
class Processor
{
public void DoWork() { ... }
public void UpdateResources(int x) { ... }
}
class Algorithm
{
private volatile Processor _processor; // added volatile keyword
public void Run()
{
_processor = new Processor();
_processor.DoWork();
_processor = null;
}
public void UpdateResources(int x)
{
_processor?.UpdateResources(x);
}
}
替代2
class Processor
{
public void DoWork() { ... }
public void UpdateResources(int x) { ... }
}
class Algorithm
{
private Processor _processor;
public void Run()
{
_processor = new Processor();
Thread.MemoryBarrier(); // Added memory barier
_processor.DoWork();
_processor = null;
}
public void UpdateResources(int x)
{
Thread.MemoryBarrier(); // Added memory barier
_processor?.UpdateResources(x);
}
}
编辑: 正如您在留言建议,请参阅更好地解释代码:
class Processor
{
private int resources = Environment.ProcessorCount;
public void DoWork()
{
/*do some long running job using avaliable resources*/
}
public void UpdateResources(int x)
{
resources = x;
}
}
class Algorithm
{
private volatile Processor _processor;
public void Run()
{
_processor = new Processor();
_processor.DoWork();
_processor = null;
}
public void UpdateResources(int x)
{
_processor?.UpdateResources(x);
}
}
class Program
{
static void Main(string[] args)
{
var algorithm = new Algorithm();
var result = Task.Run(() => algorithm.Run());
// The resources were required for other staff and are reduced
algorithm.UpdateResources(1);
// The resources are reassigned for the long running algorithm
algorithm.UpdateResources(10);
// wait until the algorithm finishes
result.Wait();
// this update should have no effect as the Run method has finished and _processor is null
algorithm.UpdateResources(10);
}
}
当你运行代码时发生了什么? – Fabulous
另外考虑如果https://stackoverflow.com/questions/3556351/why-we-need-thread-memorybarrier没有解决您的查询 – Fabulous
“的第二个线程” - 既不是线程是第一或第二个 - 他们只是不同的线程;在“Run”甚至被调用之前,“第二个”线程可以完成它所需的一切......在这种情况下:“_processor”的值是多少? –