对paralell更新变量感到困惑

时间:2015-07-28 01:49:24

标签: c#

我是C#的新手,有一个问题想问你。关于" parallell更新变量"

的问题

我的代码如下:

private void Form1_Load(object sender, EventArgs e)
{
    Control.CheckForIllegalCrossThreadCalls = false;
    // ---------------------------

    Thread tTrue = new Thread(new ThreadStart(TrueThread));
    tTrue.Start();

    Thread tFalse = new Thread(new ThreadStart(FalseThread));
    tFalse.Start();
}

bool Start = false;
bool value;

void TrueThread()
{
    while (true)
    {
        if (Start == true)
        {
            value = true;
            break;
        }
    }
}

void FalseThread()
{
    while (true)
    {
        if (Start == true)
        {
            value = false;
            break;
        }
    }
}

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show(value.ToString());
}

private void button2_Click(object sender, EventArgs e)
{
    Start = true;
}

代码说明: 首先,当我的应用程序启动时 - >调用TrueThread和FalseThread 当TrueThread和FalseThread开始时,他们将检查"开始"值,当Start变量变为" true" (默认情况下为false,单击button2时将设置为true),TrueThread将设置" value" varibale为true,FalseThread将设置" value"变量为false。

但我很困惑,哪个线程会先运行?和#34;值的最终值"会是真是假?为什么?

单击button1查看结果

1 个答案:

答案 0 :(得分:0)

如果没有正确的同步,就无法对您的问题给出明确的答案。除非您同步对共享变量的访问并提供特定的执行顺序,否则您无法知道哪个线程将首先运行以及哪个线程将首先完成其工作(即使它们具有与示例中一样简单的实体)。这意味着您无法可靠地预测value变量的最终值。

相同的代码可能在不同的硬件上,在不同的主要(和次要)版本的Windows上,或者在同一个版本上,但在不同的时间运行(取决于负载的多少),表现不同(并产生不同的最终结果)系统处理等。)

这就是存在同步原语(如关键部分,互斥体等)的原因:协调多个线程的工作并使可靠地预测最终结果,同时利用并行处理。

在一个更复杂的程序中,可以在多个线程上设置共享变量(如代码中的value),如果您不同步线程,则可能导致无效状态。

考虑这个(相当简单的)例子:

// thread 1
value = true;

// ...

if ( value == true )
{
    // #1: at this point, thread 1 may get suspended; go to #2

    // do something critical
}

// thread 2
if ( value == false )
{
    // do something mutually exclusive, also critical

    // #3: if value got changed to false  after thread 1 enters the 'if'
    // this code will also execute, even though it's mutually exclusive;
    // we reached a bad state
}

// thread 3
// #2: if this runs just at the "right" time, 'value' gets overwritten
// while thread 1 is already inside the 'if'; go to #3
value = false;

由于您无法准确判断value何时设置为truefalse,因此您无法保证只会执行其中一项重要任务。您必须同步对value的访问权限,以确保一旦一个线程设置其值,其他threds就会看到最新值,而不是介于两者之间。

不可否认,这个例子有点人为,但它确实说明了一个可能的问题(很多)没有正确的同步。 (在这种简单的情况下,使用lock可以解决问题。还有一些特定的数据结构,如BlockingCollectionConcurrentDictionary等,用于提供对各种安全访问跨多个线程的数据结构。)