How do I Sleep for a specified amount of time and relinquish contr

G

Guest

In the docs for Thread.Sleep() it appears unless I specify 0 my thread will
still use the rest of its quanta (I guess doing nothing useful) as opposed to
being suspended right away to allow other runable thread to execute.

What's the best way to sleep for a specified amount of time and relinquish
control right away as opposed to using up the rest of my quanta? Do I need
to call the Win32 Sleep()? Do I need to call WaitOne() on a synchronization
object?
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
M

Michael Nemtsev

Hello nickdu,

Use TimeSpan as param of the Thread.Sleep method
For example Thread.Sleep (TimeSpan.FromSeconds (30)); //sleep for 30 secs

for example
n> In the docs for Thread.Sleep() it appears unless I specify 0 my
n> thread will still use the rest of its quanta (I guess doing nothing
n> useful) as opposed to being suspended right away to allow other
n> runable thread to execute.
n>
n> What's the best way to sleep for a specified amount of time and
n> relinquish control right away as opposed to using up the rest of my
n> quanta? Do I need to call the Win32 Sleep()? Do I need to call
n> WaitOne() on a synchronization object?
n>
n> (e-mail address removed)
n> remove "nospam" change community. to msn.com
---
WBR,
Michael Nemtsev [C# MVP] :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
G

Guest

That's what I was doing which didn't appear to be working based on my
observations. Yes, the thread that executed Sleep(<30 second timespan>) was
stopped from doing anything useful for 30 seconds, but it also appeared to be
consuming the rest of the thread's quanta. What I did instead, which appears
to do what I want is:

wait = new AutoResetEvent(false);
while (true)
{
// do some work
...
wait.WaitOne(thinkTime, true);
}

So I wait on an event that will never be signaled and I specify as a timeout
the amount of time I want to sleep. Based on my observations I don't have
the odd behavior I was seeing before which seems to be explained by the
thread continuing to use its quanta when sleeping.

I'm guessing calling the Windows Sleep() API via pinvoke would also solve my
problem, but that's just a guess.
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
M

Michael Nemtsev

Hello nickdu,

n> That's what I was doing which didn't appear to be working based on my
n> observations. Yes, the thread that executed Sleep(<30 second
n> timespan>) was stopped from doing anything useful for 30 seconds, but
n> it also appeared to be consuming the rest of the thread's quanta.

Don't u mix this with SpinWait method?
When u waits or sleep a thread relinquish its allocation of CPU time and
WaitSleepJoin is set to the ThreadState property


---
WBR,
Michael Nemtsev [C# MVP] :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
G

Guest

No, I'm not mixing Sleep() with SpinWait(). I believe Sleep(), as
implemented by the .NET framework, is not relinquishing control to runnable
threads. And it even mentions this in the docs. It say something to the
effect of "specify 0 to relinquish control to runnable threads". And based
on my observations it appears to be behaving that way, not relinquishing
control as soon as I call Sleep(). It appears to be finishing using its
quanta. And based on the fact that the behavior improved to what I was
looking to achieve when I changed it to a WaitOne(), I would say that Sleep()
with a non zero value is not really doing what I want, and maybe not doing
what many others are thinking it should do.
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
C

Chris Mullins

Sleep(0) and Sleep(1) do have a few minor differences between then, aside
from the obvious.

The key is that Sleep(0) won't allow any lower priority threads to be
scheduled, whereas Sleep(1) will.

Lots of good detail by Joe Duffy at:
http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx

--
Chris Mullins, MCSD.NET, MCPD:Enterprise
http://www.coversant.net/blogs/cmullins

nickdu said:
No, I'm not mixing Sleep() with SpinWait(). I believe Sleep(), as
implemented by the .NET framework, is not relinquishing control to
runnable
threads. And it even mentions this in the docs. It say something to the
effect of "specify 0 to relinquish control to runnable threads". And
based
on my observations it appears to be behaving that way, not relinquishing
control as soon as I call Sleep(). It appears to be finishing using its
quanta. And based on the fact that the behavior improved to what I was
looking to achieve when I changed it to a WaitOne(), I would say that
Sleep()
with a non zero value is not really doing what I want, and maybe not doing
what many others are thinking it should do.
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com


Michael Nemtsev said:
Hello nickdu,

n> That's what I was doing which didn't appear to be working based on my
n> observations. Yes, the thread that executed Sleep(<30 second
n> timespan>) was stopped from doing anything useful for 30 seconds, but
n> it also appeared to be consuming the rest of the thread's quanta.

Don't u mix this with SpinWait method?
When u waits or sleep a thread relinquish its allocation of CPU time and
WaitSleepJoin is set to the ThreadState property


---
WBR,
Michael Nemtsev [C# MVP] :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do
not
cease to be insipid." (c) Friedrich Nietzsche
 
P

Peter Duniho

nickdu said:
No, I'm not mixing Sleep() with SpinWait(). I believe Sleep(), as
implemented by the .NET framework, is not relinquishing control to
runnable
threads.

Sleep() as implemented by the .NET Framework had better just be calling the
Windows API function Sleep(). And that does indeed cause the calling thread
to immediately be suspended, with the next runnable thread being scheduled
for the CPU.
And it even mentions this in the docs. It say something to the
effect of "specify 0 to relinquish control to runnable threads".

That's right. If you don't want to sleep for any specific amount of time,
but still want to give up your timeslice to other runnable threads, you call
Sleep() with the parameter of 0.

That doesn't mean that calling it with some other value doesn't also
relinquish the CPU. It just means that if *all* you want to do is
relinquish the CPU, you can use the value of 0.
And based
on my observations it appears to be behaving that way, not relinquishing
control as soon as I call Sleep(). It appears to be finishing using its
quanta.

Define "my observations". What makes you believe that after calling
Sleep(), your thread continues to run out its timeslice?
And based on the fact that the behavior improved to what I was
looking to achieve when I changed it to a WaitOne(), I would say that
Sleep()
with a non zero value is not really doing what I want, and maybe not doing
what many others are thinking it should do.

You haven't described your observations, so how do you justify your claim
that calling WaitOne() with a timeout "behaves better" than simply calling
Sleep() with the same timeout?

Pete
 
C

Chris Mullins

Peter Duniho said:
Sleep() as implemented by the .NET Framework had better just be calling
the Windows API function Sleep(). And that does indeed cause the calling
thread to immediately be suspended, with the next runnable thread being
scheduled for the CPU.

Well, it's not that simple. (It never is, is it?)

On hyperthreaded processors, the behavior is slighly different. Jeff Richter
goes into this a tiny bit at:
http://msdn.microsoft.com/msdnmag/issues/05/10/ConcurrentAffairs/
http://msdn.microsoft.com/msdnmag/issues/05/10/ConcurrentAffairs/default.aspx?loc=&side=true#a

If I understood the issues here better, I would explain them. I'm hoping
someone much smarter than me fills in all the issues here.
That doesn't mean that calling it with some other value doesn't also
relinquish the CPU. It just means that if *all* you want to do is
relinquish the CPU, you can use the value of 0.

There are some good reasons no to use "0" as the value passed to sleep. Joe
Duffy goes into the details at:
http://www.bluebytesoftware.com/blog/PermaLink,guid,1c013d42-c983-4102-9233-ca54b8f3d1a1.aspx
What makes you believe that after calling Sleep(), your thread continues
to run out its timeslice?

Ya know, if I had to figure that out, and had full access to the machine
with all the hardcores debuggers I could find, it would stil be VERY hard to
figure out. I would be (pleasently) shocked to see an easy way to determine
this.
 
G

Guest

From reading the docs I'm remember it saying something about continuing to
use the thread's quanta. I don't think the .NET Thread.Sleep() simply calls
the Win32 Sleep() API.

You're correct that I didn't go into specifics on my observations which I
will do now. I started looking into this because a load simulator I wrote to
simulate a bunch of clients against our SQL database was exhibiting some
weird behavior. I noticed that about every 20 seconds or so the output of my
routine would pause for about 10 seconds. By the way, this was run on an 8
way machine and I started 100 threads each opening a connection to the
database and executing queries with a 30 second think time. The think time I
simulated with a Sleep() call. So I first figured that SQL might be having
some problems which was causing my delay. I ran a SQL profile session and
all the numbers looked pretty good, in the 10 to 20 ms range. So then I
figured it was my client program. After reading the part about Sleep()
continuing to use the thread's quanta I decided to use a wait function to see
if that would produce any better results. And indeed it did. I no longer
see the delay in my output.
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
P

Peter Duniho

Chris Mullins said:
[...]
That doesn't mean that calling it with some other value doesn't also
relinquish the CPU. It just means that if *all* you want to do is
relinquish the CPU, you can use the value of 0.

There are some good reasons no to use "0" as the value passed to sleep.

This is true, depending on what your goals are. I did not intend my reply
to be a fully detailed treatise on the exact behavior of Sleep(). However,
the OP is claiming that even when he calls Sleep() with a *non-zero* value,
the thread continues to run until the timeslice is finished.

I hope we can agree that this is a *highly* unlikely scenario.

Pete
 
P

Peter Duniho

nickdu said:
From reading the docs I'm remember it saying something about continuing to
use the thread's quanta.

From reading which docs? It just makes no sense that any version of Sleep()
would in fact do a spin wait until the timeslice is up. The moment you call
Sleep() (.NET or Windows API) with a non-zero value, that thread should be
suspended (and most of the time even with zero passed to it). I have a hard
time believing you've seen any official documentation that says otherwise.

The fact that using the wait-on-an-event method instead changes the behavior
doesn't prove that Sleep() was using up the timeslice. It just means it
does something different that changed the behavior.

Pete
 
J

Jeffrey Tan[MSFT]

Hi Nick,

It costs me some time to read all your discussions with the community
before I can provide a reply to you.

I am not sure if I understand you completely. Based on my understanding,
you are writting a stress simulator application for SQL Server. After
openning a connection to the SQL Server, the thread uses Thread.Sleep()
method to simulate 30 second *processing time*(think time). However, every
20 seconds or so the output of your routine would pause for about 10
seconds, so you wanted to find out the root cause of this problem. If I
have misunderstood you, please feel free to tell me, thanks.

The point that I do not understand well is what "output of your routine
pause for 10 seconds" means. Can you tell me what is this "routine"? How
does the routine generate output?

Another point:
Sleep() continuing to use the thread's quanta I decided to use a wait function to see
if that would produce any better results
I think I do not understand your expected behavior completely. Can you
telll me what is the "better result" behavior? Then I will judge to see why
Thread.Sleep() does not meet your need. Thanks.

Anyway, I wanted to share some information with you:

1. .Net2.0 System.Threading.Thread.Sleep() method internally calls Win32
SleepEx() API. I can prove this by setting a breakpoint in Kernel32!SleepEx
API in windbg for a .Net2.0 Winform application. Below is the call stack I
got while I call Thread.Sleep() method in .Net:

0:000> !dumpstack
Current frame: KERNEL32!SleepEx
ChildEBP RetAddr Caller,Callee
0013f230 792144fc mscorwks!Thread::UserSleep+0x93, calling KERNEL32!SleepEx
0013f250 79214574 mscorwks!ThreadNative::Sleep+0x30, calling
mscorwks!Thread::UserSleep
0013f260 011a03a6 011a03a6
0013f28c 79bbaeb0 (stub for System.Threading.Thread.Sleep), calling
011a037c
0013f290 0111026f (MethodDesc 0xc253c8 +0x17
winformtest.Form1.button1_Click), calling 79bbaeab (MethodDesc 0x79bbaeb0
System.Threading.Thread.Sleep)
0013f2a0 7b881fa4 (MethodDesc 0x7b9e5108 +0x54
System.Windows.Forms.Control.OnClick)

If you want to know more detailed information, you may download SSCLI2.0
project to view the sample source code of ThreadNative::Sleep,
Thread::UserSleep of CLR.
"Shared Source Common Language Infrastructure 2.0 Release"
http://www.microsoft.com/downloads/details.aspx?FamilyId=8C09FD61-3F26-4555-
AE17-3121B4F51D4D&displaylang=en

2. In Windows thread schedulling, any wait operation will be decreased 1
point of quantum unit. And the default thread quantum has about 3 quantum
units to run. So after Sleep(30000) calling, the calling thread will go
into wait state for 30 seconds, then its quantum will reduce 1 unit. Note:
once in wait state, this thread can not be scheduled for execution, other
thread will execute. Also, after wakeup, the calling thread will not run
immediately, it will be placed in the read thread queue for scheduling.

For event/semaphore, it will normally behaves the same as Thread.Sleep().
However, after wakeup, Windows will provide a special priority boost to the
calling thread, so that the wakeup thread can run immediately. I am not
sure if this difference is the root cause of your problem.

3. If you think your simulator application is hanging for 10 seconds, the
best technology to troubshoot is using "Process Explorer" to examine what
each thread is hanging about. You may just examine each thread call stack
during this 10 seconds hang. The call stack will reveal what's going on.
The following article may not be very relevant to your question, but it
demonstrates how to troubleshoot the hang/delay style problem:
http://www.codeproject.com/system/NoDeleteDelay.asp

Finally, the Windows thread scheduling is not a trivial topic, it is
covered best in Chapter 6 of Mark E. Russinovich's wonderful book <Windows
Internals>. More specificly, "Thread Scheduling" section is dedicated for
this topic. You may give it a reading to understand more background
information.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
K

Kevin Spencer

I take Sonata every night, just before bedtime, since once I get to sleep, I
generally stay asleep. However, under stress, I occasionally add Lorazepam
to the mix.

--
;-),

Kevin Spencer
Microsoft MVP
Ministry of Software Development
http://unclechutney.blogspot.com

Any experience you can walk away from
is a good one.



Peter Duniho said:
Chris Mullins said:
[...]
That doesn't mean that calling it with some other value doesn't also
relinquish the CPU. It just means that if *all* you want to do is
relinquish the CPU, you can use the value of 0.

There are some good reasons no to use "0" as the value passed to sleep.

This is true, depending on what your goals are. I did not intend my reply
to be a fully detailed treatise on the exact behavior of Sleep().
However, the OP is claiming that even when he calls Sleep() with a
*non-zero* value, the thread continues to run until the timeslice is
finished.

I hope we can agree that this is a *highly* unlikely scenario.

Pete
 
G

Guest

I tried to go back and find the docs I'm referring to but can't. So the only
conclusion I can come to is that I somehow read that into the docs based on
seeing the part about specifying zero to relinquish control to other waiting
threads.

Though I don't think this caused me to see something in the behavior of my
program after making the change that really isn't there. I no longer see
this considerable lag in my output (which I'm doing via a
Console.WriteLine()). Maybe that's explained by Jeffrey's post where he
mentions that the OS will boost the priority of a thread after a Wait().
--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
P

Peter Duniho

nickdu said:
[...] I no longer see
this considerable lag in my output (which I'm doing via a
Console.WriteLine()). Maybe that's explained by Jeffrey's post where he
mentions that the OS will boost the priority of a thread after a Wait().

Could be. Since you still have failed to provide any actual code or
detailed description of what is actually happening, it's very hard for
anyone else to say.

All I'm saying is that I'm practically certain that when you call Sleep()
with a non-zero value, your thread does not continue running.

Pete
 
G

Guest

Here is the code in question.

try
{
portfolios = eom.Portfolios[Eom.Side.Client];
foreach(Eom.IPortfolio port in portfolios)
{
list.Add(port.Name);
}
names = (string[]) list.ToArray(typeof(string));

while (true)
{
// Thread.Sleep(this._thinkTime);
wait.WaitOne(this._thinkTime, true);
name = names[rand.Next(0, names.Length)];
portfolio = (Eom.IClientPortfolio) portfolios[name];

orders = portfolio.Orders;
if (orders != null)
{
foreach(Eom.IOrder orer in orders)
{
}
}

marketPortfolios = portfolio.MarketPortfolios;

foreach (Eom.IProperty prop in portfolio.Properties)
{
}

// Set some properties

// Set client portfolio property at client portfolio.

property = portfolio.Properties[Eom.Properties.TradingInstructions];

if (property != null)
property.Value = "Nick's trading instructions.";
else
portfolio.Properties.Add(Eom.Properties.TradingInstructions, "Nick's
trading instructions.");

// Set client order property at client portfolio.

property = portfolio.Properties[Eom.Properties.Guaranteed];
if (property != null)
property.Value = true;
else
portfolio.Properties.Add(Eom.Properties.Guaranteed, true);

// Set client order property at client order.

}
}
catch(Exception e)
{
Console.WriteLine("Worker encountered the following exception:\n\n{0}",
e.ToString());
throw;
}

--
Thanks,
Nick

(e-mail address removed)
remove "nospam" change community. to msn.com
 
J

Jeffrey Tan[MSFT]

Hi Nick,

Thanks for your feedback.

Most part of the code snippet you provided is the business code of your
application which is not informative regarding the Sleep/Event.WaitOne
delay. It is hard for us to provide any further information based on this
code snippet. Thanks for your understanding.

Can you provide more information regarding the "output rountine" in your
application and thread modeling in your application? Also, what is the
"better result" behavior as you described?

Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top