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); Release CPU time slice thread.sleep (+); Sleep 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) The time to abandon the CPU is just enough for other active threads in the time slice queue (if any) to be executed.
Thread.Sleep in the blocking method is the only way to pause capturing Windows messages for Windows Forms programs, which is a big problem in Windows Forms programs, and any blocking of the main UI thread will cause the program to lose its corresponding. Therefore, this is generally avoided, regardless of whether information acquisition is "technically" tentative or not. 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. The 50 iteration pauses for about a microsecond, typically depending on the speed and load of the CPU. Technically, spinwait is not a blocking method: A threadstate in a spin-waiting thread is not a waitsleepjoin state and will not be prematurely interrupted by another thread (Interrupt). SpinWait is rarely used, and its role is to wait for a predictable resource that can be prepared in a very short time (possibly less than a microsecond) without having to call the sleep method to block threads and waste CPU time. However, the advantage of this technology is only in multiprocessor computers: on a single processor computer, 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 takes a long time, which in 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 (!proceed) thread.sleep (x); "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 kind of polling and hibernation can be combined very well, perhaps its greatest usefulness is that programmers can abandon the use of complex signal structures to work.
Use join to wait for a thread to complete
You can block a thread until another thread ends by using the Join method:
Class Threaddemo { static void Main () { thread t = new Thread (delegate () {console.readline ();}); T.start (); T.join (); Wait until the thread finishes Console.WriteLine ("Thread T ' s ReadLine complete!");} }
The Join method also receives a time-out parameter that uses milliseconds or a TimeSpan class, and returns True when the join timeout is returned false if the thread has terminated.
Join takes a time-out parameter very much like the sleep method, in fact the following two lines of code are almost the same:
Thread.Sleep (1000);
Thread.CurrentThread.Join (1000);
Their difference is evident in the single-threaded application domain and COM interoperability: When blocking, join keeps information captured and sleep pauses information capture.
C # Multithreading Practice-Thread synchronization