[Windows] thread discussion-key section of Thread Synchronization

Source: Internet
Author: User

This series is intended to record the knowledge points of windwos threads, including thread basics, thread scheduling, thread synchronization, TLS, and thread pool.

 

Key Section

The key section is a short section.CodeIt requires exclusive access to some shared resources before execution. This method allows multiple lines of code to manipulate resources in an atomic manner. Here, the atomic method means that the code knows that no thread except the current thread will access the resource at the same time. Of course, the system can still pause the current thread to schedule other threads. However, before the current thread leaves the key segment, the system will not schedule any other threads that want to access the same resource.

The following code shows how to use the critical section:

Const int COUNT = 10; int g_nsum = 0; critical_section g_cs; // critical_section structdword winapi firstthread (pvoid pvparam) {entercriticalsection (& g_cs); // try enter critical sectiong_nsum = 0; for (INT n = 1; n <= count; n ++) g_nsum + = N; leavecriticalsection (& g_cs); Return (g_nsum);} DWORD winapi secondthread (pvoid pvparam) {entercriticalsection (& g_cs); // try enter critical sectiong_nsum = 0; For (INT n = 1; n <= count; n ++) g_nsum + = N; leavecriticalsection (& g_cs); Return (g_nsum );}

If the preceding entercriticalsection and leavecriticalsection are not available, the g_nsum state is unpredictable when the two thread functions are executed in two threads respectively.

in the above Code, a critical_section data structure named g_cs is defined first, and any resources to be accessed (g_nsum) the code is placed between entercriticalsection and leavecriticalsection . Note that the key section must be used in all related threads (that is, the two preceding thread functions must be included in the key section ), otherwise, shared resources may be damaged (as long as you have a clear understanding of thread scheduling, it is easy to understand the reasons ). In addition, initializecriticalsection must be called before entercriticalsection initialization. When you do not need to access shared resources, you should call deletecriticalsection:

/* Sample C/C ++, windows, link to kernel32.dll */# include <windows. h> static critical_section Cs;/* This is the critical section object -- once initialized, it cannot be moved in memory * // * If you program in OOP, declare this as a non-static member in your class * // * initialize the critical section before entering multi-threaded context. */initializecriticalsection (& CS); void F () {/* enter Critical section -- other threads are locked out */entercriticalsection (& CS);/* do some thread-safe processing! * // * Leave the critical section -- other threads can now entercriticalsection () */leavecriticalsection (& CS );} /* release system object when all finished -- usually at the end of the cleanup Code */deletecriticalsection (& CS );

 

How key segments work

Entercriticalsection checks some member variables in critical_section, which indicate whether a thread is accessing resources:

    • If no thread is accessing the resource, entercriticalsection updates the member variable to indicate that the calling thread has been authorized to access the resource and returns immediately, so that the thread can continue to execute.
    • If the member variable represents the call threadAlreadyIf you are authorized to access resources, entercriticalsection updates the variable to indicate that the call thread is allowed to accessTimes.
    • If the member variable indicates that other threads have been authorized to access resources, entercriticalsection uses an event kernel object to switch the current thread to the waiting state. In this way, the thread does not consume the CPU as the previous article described the spin lock.

The core value of a key segment is that it can perform all these tests in an atomic manner. In addition, tryentercriticalsection and entercriticalsection have the same ability to detect shared resources, but do not block the calling thread.

 

Key segment and rotation lock

Another core value of a key segment is that it can use a rotation lock to compete for shared resources for a certain period of time ", instead of letting the thread enter the waiting state and kernel mode immediately (it takes about 1000 CPU cycles to switch the thread from user mode to kernel mode ). In many cases, shared resources do not take too long. If you switch the thread to the kernel mode because of a shared resource to be released, it is not worth the candle. Therefore, by default, before the thread is blocked in the key segment, the system will try to use the rotation lock Multiple times to "compete" for resources. If the "contention" is successful during this period, the entercriticalsection will return, the Code enters the key segment for execution. If the Code fails, the thread is switched to the waiting state. Note that key segments can try this feature only in multi-core scenarios.

To use the rotation lock when using the key segment, you must use the following function to initialize the key segment:

Bool winapi initializecriticalsectionandspincount (_ out lpcritical_section lpcriticalsection, _ in DWORD dwspincount );

The following function is used to change the number of rotations of key segments:

 
DWORD winapi setcriticalsectionspincount (_ inout lpcritical_section lpcriticalsection, _ in DWORD dwspincount );

The key section can also be used with the condition variable, which will be covered in the next article.

For more information about key segments, see: http://blog.csdn.net/morewindows/article/details/7442639

Finally, a simple LOG method with a buffer queue is designed, which requires thread security. The implementation of C ++ is given below:

Void log (INT nlevel, const wchar * message) {struct delayedloginfo {int level; STD: wstring message ;}; static STD: List <delayedloginfo> c_logdelay; // If (tryentercriticalsection (& g_cslog, if it fails, try to get the access permission to the queue in else {entercriticalsection (& g_cslogdelay); // before reading the queue, get the access permission for the variable that represents the queue while (! C_logdelay.empty () // write all the items in the queue in a loop {delayedloginfo & loginfo = c_logdelay.front (); loginternal (loginfo. level, loginfo. message. c_str (); c_logdelay.erase (c_logdelay.begin ();} leavecriticalsection (& g_cslogdelay ); // release the access permission of the variable that represents the "queue" // The code here releases the shared object of the queue. Therefore, when the log is actually written below, other threads trying to write logs can only write data to the Buffer Queue // log the messageloginternal (nlevel, message); leavecriticalsection (& g_cslog);} else {entercriticalsection (& g_cslogdelay ); // get the access permission for the variable that represents the "queue" before writing the queue delayedloginfo loginfo = {nlevel, message}; c_logdelay.push_back (loginfo); // write the queue leavecriticalsection (& g_cslogdelay ); // release the access permission for the variable indicating "queue }}

labor fruit, reprinted please indicate the source: http://www.cnblogs.com/P_Chou/archive/2012/06/20/critical-section-in-thread-sync.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.