Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何激发对共享资源的同时访问?_C#_Multithreading_Locking - Fatal编程技术网

C# 如何激发对共享资源的同时访问?

C# 如何激发对共享资源的同时访问?,c#,multithreading,locking,C#,Multithreading,Locking,我正在创建一个对输入执行顺序处理的组件。因为它将被托管在几个不同的进程中,所以我需要它是线程安全的。起初,我故意在代码中忽略了线程安全性。现在是介绍这一点的时候了 首先,我想先挑起一个错误,但没能。以下是处理引擎代码的简化版本: public Document DoOrchestration(Document input) { Document output = new Document(); foreach (var orchestrationStep in m_Orches

我正在创建一个对输入执行顺序处理的组件。因为它将被托管在几个不同的进程中,所以我需要它是线程安全的。起初,我故意在代码中忽略了线程安全性。现在是介绍这一点的时候了

首先,我想先挑起一个错误,但没能。以下是处理引擎代码的简化版本:

public Document DoOrchestration(Document input)
{
    Document output = new Document();

    foreach (var orchestrationStep in m_OrchestrationSteps)
    {
        var processor = GetProcessor(orchestrationStep).Clone();

        output = processor.Process(input);

        input = output;
    }

    return output;
}
处理器可以由我组织中的其他人开发,这可能包括一些复杂的初始化。它们也可能是线程不安全的,所以我使用Prototype模式来获取的唯一实例,以避免其中的线程问题

为了测试此功能,我使用了以下代码:

for (int i = 0; i < 20000; i++)
{
    Thread t = new Thread(() => TestOrchestration(i));
    t.Start();
}

void TestOrchestration(int number)
{
    Document doc = new Document(string.Format("Test {0}", number));
    doc = DoOrchestration(doc);
    if (doc.ToString().Substring(0,35) != strExpectedResult)
    {
        System.Console.WriteLine("Error: {0}", doc.ToString();
    }
}
for(int i=0;i<20000;i++)
{
线程t=新线程(()=>TestOrchestration(i));
t、 Start();
}
void TestOrchestration(整数)
{
documentdoc=新文档(string.Format(“Test{0}”,number));
doc=门胸围(doc);
if(doc.ToString().Substring(0,35)!=strExpectedResult)
{
System.Console.WriteLine(“错误:{0}”,doc.ToString();
}
}
我原以为有些线程会与另一些线程发生冲突,并混淆它们的结果,但令我惊讶的是,这并没有发生

对此可能有一个简单而合乎逻辑的解释,但我想不起来。还是因为代码太简单,导致两个线程同时处理输入/输出变量?

请检查

国际象棋是一种发现和复制海森堡的工具 CHESS反复运行并发测试,确保 run采用不同的交错。如果交错导致 错误,国际象棋可以复制交错以改进调试。 国际象棋可用于托管程序和本机程序


我假定,由于测试功能的简单性,您的线程甚至没有时间在之前的一个大批量中完成它的工作。请考虑使用A来允许所有线程在开始计算步骤之前生成。此外,您还需要考虑增加测试用例的复杂性,例如,通过在同一个循环中执行多个相同的操作(启动一个线程是昂贵的,并且允许其他内核在您着手解决资源争用问题之前完成它们的工作)


一般来说,在较长时间内快速访问同一资源可能会引发资源争用,您的测试用例似乎不允许这样做。顺便说一句,我强烈建议您考虑线程安全性,而不是稍后介绍。使用代码时,您会有更好的理解资源访问模式的数量超过了您在以后分析代码时的数量。

我认为在下一个线程开始之前,您的测试功能几乎已经完成。您可以让所有线程在调用编排功能之前等待ManualResetEventSlim,然后设置ManualResetEventSlim
这样,所有线程实际上都会同时尝试调用编排。

如果所有线程都是男性管弦乐队几乎同时调用的,那么您可能不需要20000个线程来模拟这种行为

ManualResetEventSlim manualEvent = new ManualResetEventSlim (false);

for (int i = 0; i < 20000; i++)
{
    Thread t = new Thread(() => TestOrchestration(i));
    t.Start();
}
manualEvent.Set();

void TestOrchestration(int number)
{
    manualEvent.Wait();
    Document doc = new Document(string.Format("Test {0}", number));
    doc = DoOrchestration(doc);
    if (doc.ToString().Substring(0,35) != strExpectedResult)
    {
        System.Console.WriteLine("Error: {0}", doc.ToString();
    }
}
manualreseteventslimmanualevent=新的ManualResetEventSlim(假);
对于(int i=0;i<20000;i++)
{
线程t=新线程(()=>TestOrchestration(i));
t、 Start();
}
manualEvent.Set();
void TestOrchestration(整数)
{
manualEvent.Wait();
documentdoc=新文档(string.Format(“Test{0}”,number));
doc=门胸围(doc);
if(doc.ToString().Substring(0,35)!=strExpectedResult)
{
System.Console.WriteLine(“错误:{0}”,doc.ToString();
}
}

您可以使用
ManualResetEvent
同时继续任何数量的等待线程。

是的,这就是为什么一开始没有看到任何并发问题的原因。但是,当向AutoresetEvent发送信号时,一次只允许一个线程通过。我认为这是出于设计。因此我在更简单(更天真)另外,通过让所有线程等待bool值,并在所有线程生成后设置bool值。有趣的结果是,在我创建新文档以执行编排的行中,参数编号在线程之间发生冲突。但是,实际的编排似乎有效。@jonas samuelsson不确定为什么一次只允许一个线程?@JonasSamuelsson我应该使用ManualRecentEvent,AutoResetEvent会被设置回无信号状态,这就是只允许一个线程的原因。我已经更正了答案o use ManualResetEvents Slim是的,你绝对正确。我应该首先为线程安全而设计。H不过,在这种情况下,我的目的是创建一个对象池,并在资源管理器中为池设置保护条件,而不是在实际的业务流程引擎中。这样,我可以让多个业务流程引擎同时运行,而不是阻止对一个实例的调用。我听说过CHESS,但我尝试使用e简单的路线。我没有学习如何应用国际象棋,而是尝试自己做一个可能过于简单的测试应用。但从长远来看,五月国际象棋值得时间上的投资。。。