Fulfillment of the order of threads?

I have this simple code: (which I run on linqpad)

void Main() { for ( int i=0;i<10;i++) { int tmp=i; new Thread (() =>doWork(tmp)).Start(); } } public void doWork( int h) { h.Dump(); } 

string int tmp=i; designed for a capture variable - so each iteration will have its own value.

2 problems:

1) the numbers are not sequential, and the execution of threads is

2) sometimes I get less than 10 numbers!

Here are a few execution exits:

enter image description hereenter image description hereenter image description hereenter image description here

questions :

1) why is case 1 happening and how can I solve it?

2), why is case 2 happening and how can I solve it?

+4
source share
6 answers

They should not be expected to be consistent. Each thread gets priority as the kernel chooses . It may happen that they look consistent, purely in character, when each of them is running, but this is a pure chance.

To ensure that they are all filled, mark each new stream as IsBackground = false so that it IsBackground = false executable. For instance:

 new Thread(() => doWork(tmp)) { IsBackground = false }.Start(); 
+8
source

Threads are executed in an unpredictable order, and if the main thread ends before others, you will not get all numbers (dump () will not be executed). If you mark your streams as IsBackground = false, you will get all of them. There is no real solution for the first, except that they do not use threads (or join threads, which is actually the same).

+2
source

You should not expect any ordering between threads.

If you start a new thread, it is simply added to the operating system management structures. In the end, the thread scheduler appears and allocates a time slice for the thread. He can do this in a circular way, choose a random one, use some heuristics to determine which one is most important (for example, the one that owns the window in the foreground), etc.

If the order of the exits is relevant, you can either sort it later, or - if you know that the order has already begun before starting work - use an array in which each thread is assigned an index into which it must write its result.

Creating new threads as your example does is also very slow. For a microtask, using a thread pool is at least one order of magnitude higher.

+2
source

The nature of the flow control is random. You can solve both problems, but the overhead is too high.

  • The problem is that multiple threads are consistent on the console (or what you use to dump), overriding the synchronization mechanism is possible, but complicated and will lead to performance degradation.
  • You exit before calling all threads (see answer from @Marc Gravell)
+1
source

if ordering is important, you can use a shared queue and use a semaphore to ensure that only one thread runs at the top of the queue at a time

0
source

You can order the execution of threads, but this must be done specifically for a specific problem with a specific solution.

For example: you need this thread 1,2,3, the full phase 1 of your code, and then they move on to the next phase in the order of their identifiers (these identifiers that you assigned).

You can use semaphores to achieve behavior - search for blocking and mutual exclusion, as well as the Test-and-set method.

0
source

Source: https://habr.com/ru/post/1415343/


All Articles