Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Thread.Sleep hinder other threads?

Here is a console program want 10 threads start in batch, wait 5 seconds, and stop in batch.

static void Main(string[] args)
{
    System.Threading.Tasks.Parallel.For(0, 10, (index) =>
    {
        Action<int> act = (i) =>
        {
            Console.Write("start {0} ", i);
            Thread.Sleep(5000);
        };

        act.BeginInvoke(index, OnTaskComplete, index);
    });

    Console.ReadKey();
}

static void OnTaskComplete(IAsyncResult res)
{
    Console.Write("finish {0} ", res.AsyncState);
}

but the result is not what I expected, 10 threads start one-by-one SLOWLY(around 1 second interval), even some "finish" comes out before some "start".

when comment out Thread.Sleep, all threads start and finish in flash.

Does Thread.Sleep affect other threads? Is there anyway to make a pure idle time?

/-----------------------------edit-----------------------------

same problem also happen in:

static void Main(string[] args)
{
    System.Threading.Tasks.Parallel.For(0, 10, (index) =>
    {
        Console.Write("start {0} ", index);
        Thread.Sleep(5000);
        Console.Write("fnish {0} ", index);
    });

    Console.ReadKey();
}

----------------------Edit------------------------

finally I found a lovely way to substitute thread.sleep

static void Main(string[] args)
{
    System.Threading.Tasks.Parallel.For(0, 10, (index) =>
    {
        Console.Write("start {0} ", index);

        var t1 = new System.Threading.Timer(new TimerCallback(MyTimerCallback), index, 5000, 0); 
    });

    Console.ReadKey();
}

static void MyTimerCallback(object o)
{
    Console.Write("Timer callbacked ");
}
like image 368
demaxSH Avatar asked Jun 01 '11 02:06

demaxSH


People also ask

Does thread sleep block other threads?

Sleep method causes the current thread to immediately block for the number of milliseconds or the time interval you pass to the method, and yields the remainder of its time slice to another thread. Once that interval elapses, the sleeping thread resumes execution. One thread cannot call Thread. Sleep on another thread.

Does thread sleep block the main thread?

sleep() blocks the main UI thread [closed] Save this question. Show activity on this post.

What happens when a thread goes to sleep?

Thread. sleep causes the current thread to suspend execution for a specified period. This is an efficient means of making processor time available to the other threads of an application or other applications that might be running on a computer system.

Is thread sleep a good practice?

Using Thread. sleep() frequently in an automation framework is not a good practice. If the applied sleep is of 5 secs and the web element is displayed in 2 secs only, the extra 3 secs will increase the execution time. And if you use it more often in the framework, the execution time would increase drastically.


3 Answers

This is by design. You are seeing the threadpool manager trying to keep a limited number of threads in the executing state. Important to ensure that your program isn't running more threads than your machine has cpu cores. That's inefficient, less work gets done when Windows is forced to start swapping the cores between active threads. The threadpool manager isn't smart enough to know that the thread is sleeping and not actually performing any work.

On a dual-core machine, you'll see the first 2 threads starting right away. Then additional threads are allowed to run, one by one with a one second interval when the thread manager notices that the active threads are not making any progress and are probably blocked. The order in which threads are released and execute the Console.Write() call is not deterministic.

This is an artificial test of course, real threads don't sleep. If you have threads that block for a long time, waiting for an I/O request to complete for example then using threadpool threads (tasks) is not the best solution.

like image 191
Hans Passant Avatar answered Sep 23 '22 08:09

Hans Passant


TaskCreationOptions.LongRunning will 'remove' the ThreadPool limitation.
I don't know the easy way to specify TaskCreationOptions.LongRunning for Parallel.For.
However, you can achieve the same effect using Task class:

Action<int> action = i =>
    {
        Console.Write("start {0} ", i);
        Thread.Sleep(5000);
        Console.Write("finish {0} ", i);
    };

var tasks = Enumerable.Range(0, 100)
    .Select(arg => Task.Factory.StartNew(() => action(arg), TaskCreationOptions.LongRunning))
    .ToArray();

Task.WaitAll(tasks);

Without TaskCreationOptions.LongRunning it will run exactly the same way as your Parallel.For did.

like image 27
Alex Aza Avatar answered Sep 22 '22 08:09

Alex Aza


I updated the code slightly to show the ThreadID when writing to the Console:

Console.WriteLine("start index:{0} thread id:{1} Time:{2} ", index, Thread.CurrentThread.ManagedThreadId.ToString(), DateTime.Now.ToLongTimeString());
Thread.Sleep(5000);
ConsoleWriteLine("finish index:{0} thread id:{1} Time:{2} ", index, Thread.CurrentThread.ManagedThreadId.ToString(), DateTime.Now.ToLongTimeString());

My machine is a dual core, here's the output I get. This should give you a sense of what's happening. Remember, the loop may not always run in order, i.e.. 0 to 9, being parallel, it grabs a chunk of your array and runs each item through the lambda.

Output:

start  index:1 thread id:11 Time:11:07:17 PM
start  index:0 thread id:9  Time:11:07:17 PM
start  index:5 thread id:10 Time:11:07:17 PM
start  index:6 thread id:12 Time:11:07:18 PM
start  index:2 thread id:13 Time:11:07:19 PM
start  index:7 thread id:14 Time:11:07:20 PM
start  index:3 thread id:15 Time:11:07:21 PM
start  index:8 thread id:16 Time:11:07:22 PM
finish index:0 thread id:9  Time:11:07:22 PM
start  index:4 thread id:9  Time:11:07:22 PM
finish index:1 thread id:11 Time:11:07:22 PM
start  index:9 thread id:11 Time:11:07:22 PM
finish index:5 thread id:10 Time:11:07:22 PM
finish index:6 thread id:12 Time:11:07:23 PM
finish index:2 thread id:13 Time:11:07:24 PM
finish index:7 thread id:14 Time:11:07:25 PM
finish index:3 thread id:15 Time:11:07:26 PM
finish index:8 thread id:16 Time:11:07:27 PM
finish index:4 thread id:9  Time:11:07:27 PM
finish index:9 thread id:11 Time:11:07:27 PM
like image 25
Justin Largey Avatar answered Sep 22 '22 08:09

Justin Largey