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

前端 未结 7 2186
半阙折子戏
半阙折子戏 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-04 23:57

    There is only one reason why the main thread will finish before the created thread and that is because it takes time to start a thread. The only time you would use threads to speed up a program is when 2 tasks can be run at the exact same time. If you want to make the second loop finish first , take a look at Parallel.For loops in c#... these will run each loop in the for loop at the same time (not all of them but as much as your PC can handle)

    0 讨论(0)
  • 2021-02-04 23:59

    This is probably because Thread.Start first causes the change of state of thread on which it is called and OS schedules it for execution whereas the main thread is already running and does not need these two steps. This is probably the reason that the statement in main thread executes first rather the one in the newly created thread. Keep in mind the sequence of thread execution is not guaranteed.

    Thread.Start Method

    1) Thread.Start Method Causes the operating system to change the state of the current instance to ThreadState.Running.

    2) Once a thread is in the ThreadState.Running state, the operating system can schedule it for execution. The thread begins executing at the first line of the method represented by the ThreadStart

    Edit It seems to me that representing this in graphical form will make this more clear and understandable. I tried to show the sequence of thread execution in diagram below.

    enter image description here

    0 讨论(0)
  • 2021-02-05 00:02

    It basically needs time to start the thread up. You are running the thread code at the same time as the rest of the first method. So taking into account the time it takes to start the thread and then get to the point where it is writing the "." does that make sense?

    If you have a sort of reset button in your app to start everything again (without exiting) you may find that the first character is the "." because the thread will already exist.

    0 讨论(0)
  • 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).

    0 讨论(0)
  • 2021-02-05 00:09

    You say:

    "It is weird for me, because the t thread starts first then the main continues.".

    This is not true. The "main" tread is already running. When t.Start(); is executed, the OS is told t is in the running state. The OS will then schedule execution time for the thread "soon". This is something else than the OS is instructed to stop execution of this thread until thread t is started. In other words, when Start returns, there is no guarantee that the thread has already started executing.

    0 讨论(0)
  • 2021-02-05 00:12

    Your code is non deterministic. Your code contains no thread primitives that would schedule priority of one thread over another or for one thread to wait for another.

    0 讨论(0)
提交回复
热议问题