Why does the main thread's output come first in C#?

前端 未结 7 2184
半阙折子戏
半阙折子戏 2021-02-04 23:41

I wrote this little program:

class Program
{
    static void Main(string[] args)
    {
        Thread t = new Thread(WriteX);
        t.Start();

        for (in         


        
7条回答
  •  谎友^
    谎友^ (楼主)
    2021-02-05 00:06

    More of an advice than not an answer:

    (Please note, that I see no real-life use for what you are trying to achieve, so I treat your problem as a thought experiment/proof of a concept not explained in detail.)


    If you want your threads to "race" for control, don't give your main thread a head start! Creating a thread has some overhead and your main thread is already created (since it creates your other thread). If you are looking for a mostly equal chance for both of your main and worker thread, you should wait for your worker thread to be created in the main thread and wait for the main thread to start the race in your background thread. This can be achived by synch objects.


    In practice it would look like this:

    You should declare two ManualResetEvents which are visible for both your main- and background thread like this:

    private static ManualResetEvent backgroundThreadReady = new ManualResetEvent(false);
    private static ManualResetEvent startThreadRace = new ManualResetEvent(false);
    

    Then in your main thread, you should wait for your thread being initialized like:

    static void Main(string[] args)
    {
        Thread t = new Thread(WriteX);
        t.Start();
        backgroundThreadReady.WaitOne(); // wait for background thread to be ready
    
        startThreadRace.Set();           // signal your background thread to start the race
        for (int i = 0; i < 1000; i++)
        {
            Console.Write("O");
        }
    }
    

    And in your thread:

        private static void WriteX()
        {
            backgroundThreadReady.Set(); // inform your main thread that this thread is ready for the race
    
            startThreadRace.WaitOne();   // wait 'till the main thread starts the race
            for (int i = 0; i < 1000; i++)
            {
                Console.Write(".");
            }
        }
    

    Please note that I could have used other waitable sync objects (mutex, autoreset event, even a critical section lock with some hack, I've just choose the simplest, fastest solution which can be extended easily).

提交回复
热议问题