C#Threading:RaceCondition示例我在看http://www.mono-project.com/ThreadsBeginnersGuide。第一个示例如下所示:publicclassFirstUnsyncThreads{privateinti=0;publicstaticvoidMain(string[]args){FirstUnsyncThreadsmyThreads=newFirstUnsyncThreads();}publicFirstUnsyncThreads(){//创建我们的两个线程。ThreadStart委托指向//在新线程中运行的方法。ThreadfirstRunner=newThread(newThreadStart(this.firstRun));ThreadsecondRunner=newThread(newThreadStart(this.secondRun));//启动我们的两个线程。Thread.Sleep(10)给第一个Thread//多了10毫秒的时间。firstRunner.开始();线程睡眠(10);secondRunner.Start();}//此方法在第一个线程上执行。publicvoidfirstRun(){while(this.i<10){Console.WriteLine("Firstrunnerincrementingifrom"+this.i+"to"+++this.i);//这避免了第一个跑步者在第二个跑步者开始之前完成所有工作。(发生在高性能//机器sometimes.)Thread.Sleep(100);}}//这个方法正在第二个线程上执行。publicvoidsecondRun(){while(this.i<10){Console.WriteLine("第二个跑步者将i从"+this.i+"递增到"+++this.i);线程睡眠(100);}}}输出:第一个跑步者将i从0增加到1第二个跑步者将i从1增加到2第二个跑步者将i从3增加到4第一个跑步者将i从2增加到3第二个跑步者将i从5增加到6第一个跑步者将i从4到5第一名将i从6增加到7第二名将i从7增加到8第二名将i从9增加到10第一名将i从8增加到9哇,这是什么?不幸的是,文章中的解释对我来说还不够。您能否解释一下为什么增量会乱序发生?谢谢!我认为这篇文章的作者把事情搞混了。VoteyDisciple是正确的,++i不是原始的,如果在操作过程中没有锁定目标,可能会出现竞争条件,但这不会导致上述问题。如果在调用++i时出现竞争条件,则++运算符的内部操作将类似于:-第一个线程读取值0第二个线程读取值0第一个线程将值递增为1第二个线程将值递增为1第一个线程写入值1第二个线程写入值1操作3到6的顺序无关紧要,关键是当变量具有valuex相同的y增量,而不是每个线程对不同的x值执行增量和y。这会导致以下输出:-第一个运行者将i从0递增到1第二个运行者将i从0递增到1更糟糕的是:-第一个线程读取值0第二个线程读取值0第二个线程2个线程将值递增到1第二个线程写入值1第二个线程读取值1第二个线程将值递增到2第二个线程写入值2第一个线程将值递增到1第一个线程写入值1第二个线程读取值1第二个线程将值递增到2第二个线程线程写入值2这可能导致以下输出:-第一个跑步者将i从0递增到1第二个跑步者将i从0递增到1第二个跑步者将i从1递增到2第二个跑步者将i从1递增到2等等。此外,由于Console.WriteLine调用连接i和++i,因此在读取i和执行++i之间可能存在竞争条件。这可能会产生如下输出:–第一个运行者将i从0递增到1第二个运行者将i从1递增到3第一个运行者将i从1递增到2作者描述的令人困惑的控制台输出只能由控制台的不可预测性引起输出性别,与i变量上的竞争条件无关。在执行++i或同时连接i和++i时锁定i++i不会改变此行为。当我运行它(在双核上)时,我的输出是第一名跑步者将i从0递增到1第二名跑步者将i从1递增到2第一名跑步者将i从2递增到3第二名跑步者将i从3递增到4第一名跑步者将i从4到5第二个跑步者将i从5递增到6第一个跑步者将i从6递增到7第二个跑步者将i从7递增到8第一个跑步者将i从8递增到9第二个跑步者将i从9递增到10正如我所料。您正在运行两个循环,都执行Sleep(100)。这对于展示竞争条件非常不利。该代码确实存在竞争条件(如VoteyDisciple所述),但它不太可能浮出水面。我无法解释输出中没有顺序(是真正的输出吗?),但是Console类会同步输出调用。如果省略Sleep()调用并运行循环1000次(而不是10次),您可能会看到两个跑步者从554增加到555或其他。当有多个线程时,同步是必不可少的。在这种情况下,您会看到两个线程都对this.i进行读取和写入,但没有对同步这些访问做出任何好的尝试。由于它们同时修改相同的内存区域,因此您会观察到混乱的输出。睡眠是危险的,它是一种导致判断错误的方法。您不能假设线程最初总是偏移10毫秒。简而言之:永远不要使用Sleep进行同步:-)而是使用某种线程同步技术(例如锁、互斥锁、信号量)。始终尝试使用最轻的锁来满足您的需要……JoeDuffy的书《Windows上的并发编程》是一个有用的资源。增量不会乱序发生,Console.WriteLine(...)将多个线程的输出写入单线程控制台,从多个线程同步到单个线程会导致消息出现故障。我假设这个例子试图创造一个竞争条件,但在你的情况下失败了。不幸的是,由于它们的性质,竞争条件和死锁等并发问题很难预测和重现。您可能想尝试多运行几次,将其更改为使用更多的多线程,每个线程应该增加更多次(比如100,000)。然后您可能会看到最终结果不等于所有增量的总和(由竞争条件引起)。以上就是《C#线程:竞争条件实例分享》C#学习教程的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
