thread context switch question

  • Thread starter Thread starter William Stacey
  • Start date Start date
W

William Stacey

Using the following code sample:
public byte[] Get()
{
// <= Possible to switch Here??
lock(syncLock)
{
//Do something in Get().
}
}

It is possible for a thread switch to happen after a method is entered, but
before the first line of code in the method? I am thinking it is. tia
 
William,

Yes, I believe it is. What exactly are you trying to do?
 
William, yes, that is definitely possible. To prevent that you will have to
use one of the many thread synchronization techniques like the Monitor
class.
 
Just trying to be defensive and figure out where to subtle errors can
appear.
Thanks.
--
William Stacey, DNS MVP

Nicholas Paldino said:
William,

Yes, I believe it is. What exactly are you trying to do?

--
- Nicholas Paldino [.NET/C# MVP]
- nick(dot)paldino=at=exisconsulting<dot>com

William Stacey said:
Using the following code sample:
public byte[] Get()
{
// <= Possible to switch Here??
lock(syncLock)
{
//Do something in Get().
}
}

It is possible for a thread switch to happen after a method is entered, but
before the first line of code in the method? I am thinking it is. tia
 
Hi William,

Thread context switch can happens in many situation, so you must be more
carefully about it.
The thread context switch is based on the machine instruction, so even one
sentence of non-instruction should be locked.

For example, if you want to increace an interger as i++ in multi-thread
environment, you should use Interlocked.Increment method.
This is because the i++ will be parse as more than one instructions.

Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "William Stacey" <[email protected]>
| References: <[email protected]>
<#[email protected]>
| Subject: Re: thread context switch question
| Date: Wed, 8 Oct 2003 19:56:48 -0400
| Lines: 41
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.3790.0
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Message-ID: <#[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 66.188.59.114.bay.mi.chartermi.net 66.188.59.114
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:190047
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Just trying to be defensive and figure out where to subtle errors can
| appear.
| Thanks.
| --
| William Stacey, DNS MVP
|
| "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
| in message | > William,
| >
| > Yes, I believe it is. What exactly are you trying to do?
| >
| > --
| > - Nicholas Paldino [.NET/C# MVP]
| > - nick(dot)paldino=at=exisconsulting<dot>com
| >
| > | > > Using the following code sample:
| > > public byte[] Get()
| > > {
| > > // <= Possible to switch Here??
| > > lock(syncLock)
| > > {
| > > //Do something in Get().
| > > }
| > > }
| > >
| > > It is possible for a thread switch to happen after a method is
entered,
| > but
| > > before the first line of code in the method? I am thinking it is.
tia
| > >
| > > --
| > > William Stacey, DNS MVP
| > >
| > >
| > >
| >
| >
|
|
|
 
Thanks Jeffrey, I think I see the issue with some more digging using the
following c# code and IL.
The following C# code translates to the below IL. I guess a context switch
could happen between L_0000 and L0007. Is that how you see it?

public void TestLock()
{
lock(syncLock)
{
}
}


public void TestLock();

..maxstack 2
..locals (object V_0)
..try L_000d to L_000f finally L_000f to L_0016
L_0000: ldarg.0
L_0001: ldfld syncLock
L_0006: dup
L_0007: stloc.0
L_0008: call Monitor.Enter
L_000d: leave.s L_0016
L_000f: ldloc.0
L_0010: call Monitor.Exit
L_0015: endfinally
L_0016: ret

--
William Stacey, DNS MVP

Jeffrey Tan said:
Hi William,

Thread context switch can happens in many situation, so you must be more
carefully about it.
The thread context switch is based on the machine instruction, so even one
sentence of non-instruction should be locked.

For example, if you want to increace an interger as i++ in multi-thread
environment, you should use Interlocked.Increment method.
This is because the i++ will be parse as more than one instructions.

Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "William Stacey" <[email protected]>
| References: <[email protected]>
<#[email protected]>
| Subject: Re: thread context switch question
| Date: Wed, 8 Oct 2003 19:56:48 -0400
| Lines: 41
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.3790.0
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Message-ID: <#[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 66.188.59.114.bay.mi.chartermi.net 66.188.59.114
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:190047
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Just trying to be defensive and figure out where to subtle errors can
| appear.
| Thanks.
| --
| William Stacey, DNS MVP
|
| "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
| in message | > William,
| >
| > Yes, I believe it is. What exactly are you trying to do?
| >
| > --
| > - Nicholas Paldino [.NET/C# MVP]
| > - nick(dot)paldino=at=exisconsulting<dot>com
| >
| > | > > Using the following code sample:
| > > public byte[] Get()
| > > {
| > > // <= Possible to switch Here??
| > > lock(syncLock)
| > > {
| > > //Do something in Get().
| > > }
| > > }
| > >
| > > It is possible for a thread switch to happen after a method is
entered,
| > but
| > > before the first line of code in the method? I am thinking it is.
tia
| > >
| > > --
| > > William Stacey, DNS MVP
| > >
| > >
| > >
| >
| >
|
|
|
 
Hi William,

From the IL code you can get some image of what I mean, but acutally, the
IL code also is not the most basic code, it also can be parse into several
instructions.
So you can just regard the IL code as the virtual instructions for
understanding usage.

Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: "William Stacey" <[email protected]>
| References: <[email protected]>
<#[email protected]>
<#[email protected]>
<[email protected]>
| Subject: Re: thread context switch question
| Date: Thu, 9 Oct 2003 01:00:06 -0400
| Lines: 120
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.3790.0
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| Message-ID: <[email protected]>
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 66.188.59.114.bay.mi.chartermi.net 66.188.59.114
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP12.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:190105
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Thanks Jeffrey, I think I see the issue with some more digging using the
| following c# code and IL.
| The following C# code translates to the below IL. I guess a context
switch
| could happen between L_0000 and L0007. Is that how you see it?
|
| public void TestLock()
| {
| lock(syncLock)
| {
| }
| }
|
|
| public void TestLock();
|
| .maxstack 2
| .locals (object V_0)
| .try L_000d to L_000f finally L_000f to L_0016
| L_0000: ldarg.0
| L_0001: ldfld syncLock
| L_0006: dup
| L_0007: stloc.0
| L_0008: call Monitor.Enter
| L_000d: leave.s L_0016
| L_000f: ldloc.0
| L_0010: call Monitor.Exit
| L_0015: endfinally
| L_0016: ret
|
| --
| William Stacey, DNS MVP
|
| | >
| > Hi William,
| >
| > Thread context switch can happens in many situation, so you must be more
| > carefully about it.
| > The thread context switch is based on the machine instruction, so even
one
| > sentence of non-instruction should be locked.
| >
| > For example, if you want to increace an interger as i++ in multi-thread
| > environment, you should use Interlocked.Increment method.
| > This is because the i++ will be parse as more than one instructions.
| >
| > Hope this helps,
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| >
| > --------------------
| > | From: "William Stacey" <[email protected]>
| > | References: <[email protected]>
| > <#[email protected]>
| > | Subject: Re: thread context switch question
| > | Date: Wed, 8 Oct 2003 19:56:48 -0400
| > | Lines: 41
| > | X-Priority: 3
| > | X-MSMail-Priority: Normal
| > | X-Newsreader: Microsoft Outlook Express 6.00.3790.0
| > | X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.0
| > | Message-ID: <#[email protected]>
| > | Newsgroups: microsoft.public.dotnet.languages.csharp
| > | NNTP-Posting-Host: 66.188.59.114.bay.mi.chartermi.net 66.188.59.114
| > | Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP09.phx.gbl
| > | Xref: cpmsftngxa06.phx.gbl
| microsoft.public.dotnet.languages.csharp:190047
| > | X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
| > |
| > | Just trying to be defensive and figure out where to subtle errors can
| > | appear.
| > | Thanks.
| > | --
| > | William Stacey, DNS MVP
| > |
| > | "Nicholas Paldino [.NET/C# MVP]" <[email protected]>
| > wrote
| > | in message | > | > William,
| > | >
| > | > Yes, I believe it is. What exactly are you trying to do?
| > | >
| > | > --
| > | > - Nicholas Paldino [.NET/C# MVP]
| > | > - nick(dot)paldino=at=exisconsulting<dot>com
| > | >
| > | > | > | > > Using the following code sample:
| > | > > public byte[] Get()
| > | > > {
| > | > > // <= Possible to switch Here??
| > | > > lock(syncLock)
| > | > > {
| > | > > //Do something in Get().
| > | > > }
| > | > > }
| > | > >
| > | > > It is possible for a thread switch to happen after a method is
| > entered,
| > | > but
| > | > > before the first line of code in the method? I am thinking it is.
| > tia
| > | > >
| > | > > --
| > | > > William Stacey, DNS MVP
| > | > >
| > | > >
| > | > >
| > | >
| > | >
| > |
| > |
| > |
| >
|
|
|
 
William, it would be best if you could explain what you are trying to do
here.

In your example, if you have a context switch before the first line of code,
nothing will ever go wrong. It is designed to work that way.

If you set up your synchronization code correctly, you will always get
correct results. If you set it up incorrectly, you will occasionally get
very strange results that are very difficult to track down. The number of
machine instructions per IL instructions isn't really important here. The
fact is that you cannot assume anything is thread safe unless it is designed
that way.

Threading is a difficult subject to wrap your brain around. Find a good
article on the web, or take a look at some of the literature on threading in
Java. Java's threading model is as simple as a threading model can be.
Everything you learn from studying examples in Java can be applied to .NET
using lock() and the Monitor class (they work together). These things are
explained rather poorly in the MSDN Library, and in fact, I found the
explanations there to be somewhat misleading the first time I saw them.
Normally that's the first place you should go for info on this kind of
thing. Most topics in the MSDN Library are fantastically written and very
helpful. In this case, use other resources first.
 
Jason Smith said:
Threading is a difficult subject to wrap your brain around. Find a good
article on the web, or take a look at some of the literature on threading in
Java. Java's threading model is as simple as a threading model can be.

It's not, actually. In fact, Java's threading model has been the
subject of much debate for quite a long time, so that a new threading
model can hopefully make it into 1.5. Like many other things about
threading, it may seem simple to start with, but the devil's in the
details.

For instance, in a threading model which is "as simple as a threading
model can be" the double-check lock algorithm would work - but it
doesn't in Java (or .NET). Without looking carefully at what's going
on, that's not obvious.
 
Speaking of that. Is there a work around in .net for the double-check lock
algorithm?
 
In your example, if you have a context switch before the first line of
code,
nothing will ever go wrong. It is designed to work that way.

Not really. It would depend on you code. As you say, threading and sync
issues can be very strange and very hard to find when writing and debugging
your code. Say you have a shared object and producer/consumer threads
against it. In the shared object, you implement the GOF state pattern. So
thread1 enters a Get() in the Open state and another thread (after the
context switch) enters a Get in the closed state and runs down the whole
thing(i.e. two different methods). Another client thread could also set the
state to Closed manually before Thread1 gets the lock . Now your first Get
gets the thread back and is running code in the opened state when the state
is actually closed. This may or may not be a problem depending on your code
and there is probably many other examples of how this could effect you if
you don't guard against it.

However the point is that you have to be aware of it as it could be no
issue, a side-effect, or big problem. Most think you have to lock things
like myvar++, and that is true for many sync issues. Many do not also
realize that you may also have to lock a getter and setter for a bool or
flag - It depends on your object state and where you are at in the code when
a switch happens. So I agree this is challeging and hard to even "see" all
the potential sync issues.
Cheers!
--wjs

If you set up your synchronization code correctly, you will always get
correct results.
If you set it up incorrectly, you will occasionally get
very strange results that are very difficult to track down.

Agreed, but that kinda goes without saying.
very strange results that are very difficult to track down. The number of
machine instructions per IL instructions isn't really important here.

It is. It also helps to demonstrate the issue that any one line could be
many IL and more machine code that a context switch could happen on.

--wjs
 
William,
Your method is desigend to be thread safe. The question is whether the rest
of the methods in your class are so. Even more the qestion is whether the
returned objects' methods are thread safe. You cannot say if something is ok
to be used in multithread environment by simply looking in one isolated
method that even doesn't have meanigfull body implemented.

What I can say looking in your code is "It might be thread safe".

I can even assert that the following method might be thread safe.

public SomeObject Get()
{
//do somethig
return res;
}

So about your question. Yes it is possible for the thread scheduler to
switch the threads right before entering the critical section and there is
nothing wrong with that.

About the example with the producer/consumer you gave. This lock in the Get
method (I suppose this is the producer) doesn't guard the consuming of the
data it guards ony the process of producing it. You guarantee that data will
be produced for no more than one consumer at a time. That's it. How the
consumers will use, though, data is a matter of other methods'
implementation.

B\rgds
100
 
Your method is desigend to be thread safe. The question is whether the
rest
of the methods in your class are so. Even more the qestion is whether the
returned objects' methods are thread safe. You cannot say if something is ok
to be used in multithread environment by simply looking in one isolated
method that even doesn't have meanigfull body implemented.

That is my point as well. I was, however, asking a very specific question.
So about your question. Yes it is possible for the thread scheduler to
switch the threads right before entering the critical section and there is
nothing wrong with that.

Nothing wrong with it - agreed. You just need to understand it can happen
and see if it can effect your sync issues.
About the example with the producer/consumer you gave. This lock in the Get
method (I suppose this is the producer) doesn't guard the consuming of the
data it guards ony the process of producing it. You guarantee that data will
be produced for no more than one consumer at a time. That's it. How the
consumers will use, though, data is a matter of other methods'
implementation.

Again, I agree. I have implemented a thread safe Pipe that uses a sync'd
circular queue, so I have found (after a lot of testing) most if not all the
issues with it so far. However, it is always the ones you don't see or
don't see until that one-in-a million combination that bite you (i.e. block
forever, dead-lock, etc.)

--wjs
 
Back
Top