Why is C # the first output of the main thread?

I wrote this little program:

class Program { static void Main(string[] args) { Thread t = new Thread(WriteX); t.Start(); for (int i = 0; i < 1000; i++) { Console.Write("O"); } } private static void WriteX() { for (int i = 0; i < 1000; i++) { Console.Write("."); } } } 

I ran it about fifty times, and the first character on the console was always β€œO”. This is strange for me, because the flow t starts over, and most importantly continues.

Is there any explanation for this?

+56
multithreading c #
Jun 01 '15 at 7:24
source share
7 answers

This is probably due to the fact that Thread.Start first causes a change in the state of the thread on which it is called, and the OS plans to execute it, while the main thread is already running and does not need these two steps , This is probably the reason the operator in the main thread executes the first, and in the newly created thread. Keep in mind that thread sequence is not guaranteed.

Thread.Start Method

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

2) As soon as the thread is in ThreadState.Running state, the system can schedule its execution. The thread begins with the first line of the method represented by ThreadStart.

Change It seems to me that representing this in graphical form will make it more understandable and understandable. I tried to show the flow sequence in the diagram below.

enter image description here

+53
Jun 01 '15 at 7:33
source share

You speak:

"This is strange for me, because t stream starts over, and most importantly continues."

This is not true. The "main" tread is already running. When t.Start(); running, the OS is informed that t is operational. Then, the OS will pay the runtime for the thread "soon." This is something else, except that the OS is instructed to stop the execution of this thread until thread t begins. In other words, when Start returns, there is no guarantee that the thread has already started execution.

+20
Jun 01 '15 at 11:31 on
source share

More tips than no answer :

(Note that I do not see any real use for what you are trying to achieve, so I see your problem as a thought experiment / proof of concept that is not explained in detail.)




If you want your threads to be β€œraces” for control, don't let the main topic start the game! Creating a thread has some overhead, and the main thread has already been created (since it creates another thread). If you are looking for basically equal chances for both the main and the workflow, you should wait until your workflow is created in the main thread and wait until the main thread starts the race in the background thread. This can be achieved using synchronization objects .




In practice, it will look like this:

You must declare two ManualResetEvents elements that are visible to both the main and background threads as follows:

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

Then in the main thread, you should wait for the thread to initialize:

 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 subject:

  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 use other pending synchronization objects (mutex, autosave event, even locking a critical section with some hacks, I just choose the simplest and fastest solution that can be easily expanded).

+13
Jun 01 '15 at 7:55
source share

Basically, it takes time to start the flow up. You execute the thread code at the same time as the rest of the first method. Therefore, taking into account the time required to start the stream, and then reach the point where it writes ".". it makes sense?

If you have a kind of reset button in your application to start all over again (without exiting), you may find that the first character is β€œ.”. because the stream already exists.

+4
Jun 01. '15 at 7:28
source share

Your code is not deterministic. Your code does not contain thread primitives that plan the priority of one thread over another or wait for another for one thread.

+4
Jun 01 '15 at 7:31 on
source share

The main process will continue to execute the following instructions after calling the thread. It will take time to start the flow process as an easy process.

+4
Jun 01 '15 at 7:33
source share

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

0
Jun 02 '15 at 11:22
source share



All Articles