From: Tony Johansson on
Hi!

At the bottom is a simple thread program.
If I run this program on a computer that doesn't have two cores I always
get 100010 which is correct.
If I run this program on a computer that have two cores I sometimes get a
value that could be 96542 or 97129 or something else that less that 100010.
This is because of not doing for example lock or interlocked in this
example.

So my question is why do I always get the correct result when I run the
program on a computer with only one core ??
This computer with only one core is very old perhaps 10 years.

Class Test
{
static void UpdateCount()
{
for (int x = 0; x <= 10000; x++)
Counter.count = Counter.count + 1;
}

public static void Main()
{
ThreadStart starter = new ThreadStart(UpdateCount);
Thread[] threads = new Thread[10];

for (int x = 0; x < 10; x++)
{
threads[x] = new Thread(starter);
threads[x].Start();
}

for (int x = 0; x < 10; x++)
{
threads[x].Join();
}

Console.WriteLine("Total: {0}", Counter.count);
Console.ReadLine();
}
}

//Tony


From: Alberto Poblacion on
"Tony Johansson" <johansson.andersson(a)telia.com> wrote in message
news:OalU3zR8KHA.2248(a)TK2MSFTNGP05.phx.gbl...
> So my question is why do I always get the correct result when I run the
> program on a computer with only one core ??

Probably because the switching between threads is done every 50
milliseconds or somesuch, and the loop with 10000 iterations can be
completed in less that that time. So you never get two threads to "collide"
on the Counter.count = Counter.count+1 statement.

If you want to force the issue, you can simulate a longer running
critical zone like this:

int temp = Counter.count;
System.Threading.Thread.Sleep(100);
Counter.count = temp+1;

This one should "fail" (give a result of less than 100010) even on a
single-core computer.

From: Patrice on
Hello,

> So my question is why do I always get the correct result when I run the
> program on a computer with only one core ??

This is less likely but could happen (and more generally multithreading
problems are known to show up less with one core).

IMO this is because running two threads on a single core relies only on
thread switching. So you need thread switching to happen at the right time
in both threads to reveal the problem.

With a multi core system, you don't need thread switching to run those two
threads. As you removed a condition, the problem will be more likely to show
up...
--
Patrice


From: Arne Vajhøj on
On 11-05-2010 11:16, Tony Johansson wrote:
> At the bottom is a simple thread program.
> If I run this program on a computer that doesn't have two cores I always
> get 100010 which is correct.
> If I run this program on a computer that have two cores I sometimes get a
> value that could be 96542 or 97129 or something else that less that 100010.
> This is because of not doing for example lock or interlocked in this
> example.
>
> So my question is why do I always get the correct result when I run the
> program on a computer with only one core ??
> This computer with only one core is very old perhaps 10 years.
>
> Class Test
> {
> static void UpdateCount()
> {
> for (int x = 0; x<= 10000; x++)
> Counter.count = Counter.count + 1;
> }
>
> public static void Main()
> {
> ThreadStart starter = new ThreadStart(UpdateCount);
> Thread[] threads = new Thread[10];
>
> for (int x = 0; x< 10; x++)
> {
> threads[x] = new Thread(starter);
> threads[x].Start();
> }
>
> for (int x = 0; x< 10; x++)
> {
> threads[x].Join();
> }
>
> Console.WriteLine("Total: {0}", Counter.count);
> Console.ReadLine();
> }
> }

As stated in a previous thread, then this code is broken and
will produce random results.

And you could get other results than 100010 on a single core
system under certain circumstances.

But you have observed a tendency to get 100010 which seems to
indicate that the threads run sequentially on a single core.

That is a very likely scenario.

A thread is kicked of the CPU/core if:
- it has used its time slice (typical 10-20 milliseconds depending
on Windows version, CPU type and task type)
- another thread has a higher priority
- this thread is waiting for something (completion of IO or sleeping)

So if you threads:
- runs in less than 10 milliseonds
- all has same priority
- do no IO or sleep
then they may very likely run sequential.

Arne
From: Mihajlo Cvetanović on
On 5/11/2010 5:16 PM, Tony Johansson wrote:
> Counter.count = Counter.count + 1;

Replace this part of the code with the following and you will get wrong
results even on computer with one core. Probably.

{
int temp = Counter.count + 1;
Thread.Sleep(10);
Counter.count = temp;
}