1

I am new to C# and have a question want to ask you. Question about "parallell update a variable"

My code below:

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;
}

Code explain: First, when my application startup -> call TrueThread and FalseThread When TrueThread and FalseThread start, they will check for "Start" value, when Start variable become "true" (false by default, will be set to true when I click button2), TrueThread will set "value" varibale to true and FalseThread will set "value" variable to false.

But I confused, which thread will be run first ? and final value of "value" will be true or false ? and why ?

Click button1 to see the result

1 Answers1

0

Without proper synchronization, there's no way to give a definite answer to your question. Unless you synchronize access to shared variables and to provide a certain order of execution, you can't know which thread will run first and which thread will complete its work first (even if they have bodies as simple as in your example). This means that you cannot reliably predict the final value of your value variable.

The same code may behave differently (and produce a different end result) on different hardware, on different major (and minor) versions of Windows or indeed, on the same one but running at different times (depending on how much load the system is handling, etc.)

This is the reason synchronization primitives, like critical sections, mutexes, etc. exist: to coordinate the work of multiple threads and to make predicting the end result reliably possible, while taking advantage of parallel processing.

In a more complex program, a shared variable (like value in your code) can be set on multiple threads and it may lead to invalid state if you don't synchronize your threads.

Consider this (rather simple) example:

// 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;

Since you can't tell exactly when value gets set to true or false, you cannot guarantee that only one of the important tasks will get executed. You must synchronize access to value to make sure that once one thread sets its value, other threds see that latest value, not something in-between.

Admittedly, this example is somewhat contrived but it does illustrate one possible problem (of many) of not having correct synchronization. (In a simple situation like this, using lock would solve the problem. There are also specific data structures, like BlockingCollection, ConcurrentDictionary, etc. that are used to provide safe access to various data structures across multiple threads.)

xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • Can you give me an proper synchronization in this situation ? – Penking Nguyen Jul 28 '15 at 02:04
  • Thanks @xxbbcc, I think I must change my solution about multithreading – Penking Nguyen Jul 28 '15 at 02:22
  • @viclic Thank you for accepting my answer. I assume you're new to multithreading - if so, consider why you want to use multiple threads. They're rarely easy to use in real-world applications. I'm not trying to tell you not to use threads but if you do, make sure you understand why you use them. If you haven't read it already, read this question (especially Eric Lippert's answer): http://stackoverflow.com/questions/19382705/c-sharp-volatile-keyword-usage-vs-lock – xxbbcc Jul 28 '15 at 02:36
  • Thanks, Now I can manage my multithreading application bertter ^_^ – Penking Nguyen Jul 30 '15 at 04:11