The table below shows the list. NET tools available for coordinating or synchronizing thread actions:
Simple Blocking method
Constitute |
Objective |
Sleep |
Block a given time period |
Join |
Wait for another thread to finish |
Lock system
Constitute |
Objective |
Cross-process? |
Speed |
Lock |
Make sure that only one thread accesses a resource or a piece of code. |
Whether |
Fast |
Mutex |
Make sure that only one thread accesses a resource or a piece of code. Can be used to prevent multiple instances of a program from running concurrently. |
Is |
Medium |
Semaphore |
Make sure that no more than a specified number of threads access a resource or a piece of code. |
Is |
Medium |
Signal
Constitute |
Objective |
Cross-process? |
Speed |
EventWaitHandle |
Allows the thread to wait until it is signaled by another thread. |
Is |
Medium |
Wait and pulse* |
Allows a thread to wait until a custom throttling condition is met. |
Whether |
Medium |
Synchronization Essentials
Block (Blocking)
When a thread is in a pending or paused state by the way listed above, it is called blocked. Once blocked, the thread immediately discards its allocated CPU time, adding its ThreadState property to the WaitSleepJoin state until it stops blocking. Stop blocking is triggered by any of the following conditions:
- Conditions for blocking have been met
- The operation timed out (if timeout was specified)
- Interrupted by Thread.Interrupt.
- Abandoned by Thread.Abort.
When a thread pauses through (not recommended) The Suspend method, it is not considered to be blocked.
Hibernation and polling
Call Thread.Sleep to block the time specified by the current thread (or until interrupted):
Static void Main () { thread.sleep (0); // Releasing CPU time slices Thread.Sleep (+); // Hibernate 1000 ms Thread.Sleep (Timespan.fromhours (1)); // sleep 1 hours Thread.Sleep (timeout.infinite); // hibernate until interrupted }
To be exact, Thread.Sleep abandons the CPU, and the request is no longer allocated until more than a given time. Thread.Sleep (0) give up
The CPU time is just enough for other active threads in the time slice queue (if any) to be executed.
Thread.Sleep is the only method in the blocking method that pauses Windows message extraction from Windows Forms programs, or in a COM environment for
Cell mode. This is a big problem in the Windows Forms program, and any blocking of the main UI thread will cause the program to lose its corresponding. Therefore, generally avoid
No matter whether the information is "technically" tentative or not. The host environment left by COM is more complex, and at some point it decides to stop,
And keep the information alive. Chris Brumm of Microsoft discussed the issue in his blog. (Search: ' COM ' Chris brumme ')
The thread class also provides a spinwait method that keeps the given number of iterations "useless" by polling the CPU rather than discarding the CPU time.
To be busy. " 50 iterations may be equivalent to a pause of about a microsecond, although this will depend on the speed and load of the CPU. Technically speaking, spinwait is not a deterrent
Method: A spin-waiting thread's threadstate is not waitsleepjoin state and will not be prematurely interrupted by other threads
(Interrupt). SpinWait is rarely used, and its role is to wait for a predictable resource that can be prepared within a very short time (possibly less than a microsecond),
Instead of wasting CPU time by calling the sleep method to block threads. However, the advantage of this technology is only in multiprocessor computers: computers on a single processor,
Until the polling thread ends its time slice, a resource has no chance to change state, which is contrary to its original intention. And calling spinwait often costs more
For a long time this itself wastes CPU time.
Block vs. polling
A thread can wait for a certain condition to explicitly poll using a polling method, such as:
while (!proceed);
Or:
while (DateTime.Now < Nextstarttime);
This is a very wasteful CPU time: For the CLR and the operating system, the thread has an important calculation, so the appropriate resources are allocated! In this state
The poll thread under is not blocked, unlike a thread that waits for a eventwaithandle (typically built with such a signal task).
Blocking and polling combined use can produce some transformations:
while // "Polling hibernation!"
The larger the X, the higher the CPU efficiency, the compromise is to increase the latent time, any 20ms cost is negligible, unless the conditions in the loop are extremely complex.
In addition to a slight delay, this polling and hibernation approach can be combined very well. (But with concurrency issues, discussed in part fourth) maybe its greatest use is
Programmers can abandon the use of complex signal structures to work.
C # Multithreading Practice-Thread synchronization