对并行更新变量感到困惑
本文关键字:变量 并行 更新 | 更新日期: 2023-09-27 18:04:55
我是c#新手,有一个问题想问你。关于"并行更新变量"的问题
我的代码如下:
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和谬误线程当TrueThread和false thread启动时,它们将检查"start"值,当start变量变为"true"时(默认为false,当我点击按钮2时将设置为true), TrueThread将设置"value"变量为true,而false thread将设置"value"变量为false。
但我困惑,哪个线程将首先运行?"value"的最终值是真还是假?为什么?
点击button1查看结果
如果没有适当的同步,就无法对您的问题给出明确的答案。除非您同步访问共享变量并提供特定的执行顺序,否则您无法知道哪个线程将首先运行,哪个线程将首先完成其工作(即使它们具有像示例中那样简单的主体)。这意味着您无法可靠地预测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
何时被设置为true
或false
,你不能保证只有一个重要的任务将被执行。你必须同步访问value
,以确保一旦一个线程设置了它的值,其他线程看到的是最新的值,而不是中间的值。
无可否认,这个例子有点做作,但它确实说明了没有正确同步的一个可能的问题(许多问题)。(在这种简单的情况下,使用lock
可以解决问题。还有一些特定的数据结构,如BlockingCollection
、ConcurrentDictionary
等,用于提供跨多个线程对各种数据结构的安全访问。