Twisted Threads

You learn something new every day. As K Scott Allen points out, read or write operations to CLI datatypes larger than the native word size (32 bit on your basic PC) are not guaranteed to be atomic.

So, in the course of:

private long i = 0x00000000FFFFFFFF;

public void Increment()
{
  i++;
}

it's possible for two threads to interact as follows [edit - with hexadecimals done right this time. Idiot brain was - for some reason - only doing binary earlier.]:

iThread 1 Thread 2
0x00000000FFFFFFFF reads first four bytes of i (0x00000000)
0x00000000FFFFFFFFreads first four bytes of i (0x00000000)
0x00000000FFFFFFFFreads second four bytes of i (0xFFFFFFFF)
0x00000000FFFFFFFFincrements 0x00000000FFFFFFFF (0x0000000100000000)
0x00000001FFFFFFFFwrites first four bytes of i (0x00000001)
0x0000000100000000writes second four bytes of i (0x00000000)
0x0000000100000000 reads second four bytes of i (0x00000000)
0x0000000100000000 increments 0x0000000000000000 (0x0000000000000001)
0x0000000000000000 writes first four bytes to i (0x00000000)
0x0000000000000001 writes second four bytes to i (0x00000001)

A non-atomic read causing trouble there. A non-atomic write could be odd, too:

iThread 1 Thread 2
0x00000000FFFFFFFF reads first four bytes of i (0x00000000)
0x00000000FFFFFFFF reads second four bytes of i (0xFFFFFFFF)
0x00000000FFFFFFFF increments 0x00000000FFFFFFFF (0x0000000100000000)
0x00000001FFFFFFFF writes first four bytes to i (0x00000001)
0x00000001FFFFFFFFreads first four bytes of i (0x00000001)
0x00000001FFFFFFFFreads second four bytes of i (0xFFFFFFFF)
0x00000001FFFFFFFFincrements 0x00000001FFFFFFFF (0x0000000200000000)
0x00000002FFFFFFFFwrites first four bytes of i (0x00000002)
0x0000000200000000writes second four bytes of i (0x00000000)
0x0000000200000000 writes second four bytes to i (0x00000000)

Meaning that after calling Increment() from two threads simultaneously, the result could be that i == 0x0000000000000001, or i==0x0000000200000000, rather than the desired 0x0000000100000001 - in addition to the simple increment race condition where the reads and writes on two threads are interleaved, giving 0x0000000100000000

Tricksy things, threads...

Print | posted on Thursday, May 18, 2006 11:37 AM

Comments on this post

# re: Twisted Threads

Requesting Gravatar...
I've always maintained that there very few people in the world who can write safe and secure multi-threaded applications. I'm not one of them.
Left by Dave on May 18, 2006 12:27 PM

# re: Twisted Threads

Requesting Gravatar...
It's tricky, no doubt about it. The thought of trying to write lock free code is terrifying to me.
Left by Scott Allen on May 18, 2006 2:10 PM

# re: Twisted Threads

Requesting Gravatar...
That's funny - there are a great many people in the world who can do hexadecimal maths in their head, but clearly I'm not one of them. Apologies to anybody who was fuming at my awful maths earlier. Hopefully the hexadecimal correction above will stop the steam coning out of your ears.
Left by James on May 18, 2006 2:54 PM

# re: Twisted Threads

Requesting Gravatar...
Cool,

Thread is pain in the ass.I can never get it right

Thanks for writing, most people don't bother.
Left by software developer on Aug 13, 2009 10:11 AM

Your comment:

 (will show your gravatar)
 
Please add 6 and 2 and type the answer here: