Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread.Sleep(0) doesn't work as described?

I am currently reading this excellent article on threading and read the following text:

Thread.Sleep(0) relinquishes the thread’s current time slice immediately, voluntarily handing over the CPU to other threads.

I wanted to test this and below is my test code:

static string s = "";

static void Main(string[] args)
{
    //Create two threads that append string s
    Thread threadPoints = new Thread(SetPoints);
    Thread threadNewLines = new Thread(SetNewLines);

    //Start threads
    threadPoints.Start();
    threadNewLines.Start();

    //Wait one second for threads to manipulate string s
    Thread.Sleep(1000);

    //Threads have an infinite loop so we have to close them forcefully. 
    threadPoints.Abort();
    threadNewLines.Abort();

    //Print string s and wait for user-input
    Console.WriteLine(s);
    Console.ReadKey();
}

The functions that threadPoints and threadNewLines run:

static void SetPoints()
{
    while(true)
    {
        s += ".";
    }
}

static void SetNewLines()
{
    while(true)
    {
        s += "\n";
        Thread.Sleep(0);
    }
}

If I understand Thread.Sleep(0) correctly, the output should be something like this:

............        |
..............      |
................    | <- End of console
..........          |
.............       |
...............     |

But I get this as output:

....................|
....................|
....                |
                    |
                    |
....................|
....................|
.................   |
                    |

Seeing as the article mentioned in the beginning of the post is highly recommended by many programmers, I can only assume that my understanding of Thread.Sleep(0) is wrong. So if someone could clarify, I'd be much obliged.

like image 737
Jordy Avatar asked Jun 28 '13 13:06

Jordy


2 Answers

What thread.sleep(0) is to free the cpu to handle other threads, but that doesn't mean that another thread couldn't be the current one. If you're trying to send the context to another thread, try to use some sort of signal.

like image 141
saamorim Avatar answered Oct 17 '22 07:10

saamorim


If you have access to a machine (or perhaps a VM) with only a single core/processor, try running your code on that machine. You may be surprised with how the results vary. Just because two threads refer to the same variable "s", does not mean they actually refer to the same value at the same time, due to various levels of caching that can occur on modern multi-core (and even just parallel pipeline) CPUs. If you want to see how the yielding works irrespective of the caching issues, try wrapping each s += expression inside a lock statement.

like image 24
Dan Bryant Avatar answered Oct 17 '22 07:10

Dan Bryant