Some Thread Synchronization Methods

Source: Internet
Author: User
Tags semaphore

Unknown original source, secondhand reproduced: http://blog.sina.com.cn/s/blog_4d8205e40100gjg5.html


Critical Section
The critical section is the simplest synchronization object, which can only be used within the same process. It ensures that only one thread can apply for this object.
Void initializecriticalsectioN (maid ); Critical Section
Void deletecriticalsection (maid section ); Delete critical section
Void entercriticalsection (maid section ); Entering the critical section is equivalent to applying for locking. If the critical section is being used by another thread, the function will wait for other threads to release.
Bool tryentercriticalsection (maid section ); Entering the critical section is equivalent to applying for locking. Unlike entercriticalsection, if the critical section is being used by another thread, the function returns false immediately without waiting.
Void leavecriticalsection (maid section ); Exit the critical section, which is equivalent to applying for unlocking

The following sample code demonstrates how to use the critical section for Data Synchronization:

// Global variable
Int icounter = 0;
Critical_section cricounter;

DWORD threada (void * PD)
{
 Int IID = (INT) PD;
 For (INT I = 0; I <8; I ++)
 {
  Entercriticalsection (& cricounter );
  Int icopy = icounter;
  Sleep (100 );
  Icounter = icopy + 1;
  Printf ("thread % d: % d \ n", IID, icounter );
  Leavecriticalsection (& cricounter );
 }
 Return 0;
}
// In Main Function
{
  // Create a critical section
  InitializecriticalsectioN (& cricounter );
  // Create a thread
  Handle hthread [3];
  Cwinthread * pt1 = afxbeginthread (afx_threadproc) threada, (void *) 1 );
  Cwinthread * pt2 = afxbeginthread (afx_threadproc) threada, (void *) 2 );
  Cwinthread * pt3 = afxbeginthread (afx_threadproc) threada, (void *) 3 );
  Hthread [0] = pt1-> m_hthread;
  Hthread [1] = pt2-> m_hthread;
  Hthread [2] = pt3-> m_hthread;
  // Wait until the thread ends
  // The usage of waitformultipleobjects will be discussed later.
  Waitformultipleobjects (3, hthread, true, infinite );
  // Delete the critical section
  Deletecriticalsection (& cricounter );
  Printf ("\ nover \ n ");
}

Mutex

The mutex function is similar to that of the critical section, but the mutex can be named, that is, it can be used across processes. Therefore, creating mutex requires more resources. Therefore, if you only use it within a process, using the critical section will bring speed advantages and reduce resource occupation. Because the mutex is a cross-process mutex. Once created, you can open it by name.
Create mutex:
Handle createmutex (
 Lpsecurity_attributes lpmutexattributes,// Security Information
 Bool binitialowner,                // Initial status,
 // If it is set to true, it indicates that the thread that created it directly owns the mutex and does not need to apply for it again.
 Lptstr lpname                  // Name, which can be null, but cannot be opened by other threads/processes.
);
Open an existing mutex:
Handle openmutex (
 DWORD dwdesiredaccess,  // Access method
 Bool binherithandle,          // Whether it can be inherited
 Lptstr lpname                // Name
);
Release the right to use mutex, but the thread that calls the function must have the right to use the mutex:
Bool releasemutex (            // Act as leavecriticalsection
 Handle hmutex                  // Handle
);
Disable mutex:
Bool closehandle (
 Handle hobject                // Handle
);
If the mutex is in use, it is in the non-signal state. After the mutex is released, it becomes in the signal state. After the waiting is successful, the waitforsingleobject function sets the mutex to the non-signal state, so that other threads cannot obtain the permission and need to continue waiting. The waitforsingleobject function also supports queuing to ensure that the thread waiting for the request first obtains the right to use the object.

Int icounter = 0;

DWORD threada (void * PD)
{
 Int IID = (INT) PD;
 // Re-open it internally
 Handle hcounterin = openmutex (mutex_all_access, false, "Sam SP 44 ");

 For (INT I = 0; I <8; I ++)
 {
  Printf ("% d wait for object \ n", IID );
  Waitforsingleobject (hcounterin, infinite );
  Int icopy = icounter;
  Sleep (100 );
  Icounter = icopy + 1;
  Printf ("\ t \ tthread % d: % d \ n", IID, icounter );
  Releasemutex (hcounterin );
 }
 Closehandle (hcounterin );
 Return 0;
}

// In Main Function
{
  // Create mutex
  Handle hcounter = NULL;
  If (hcounter = openmutex (mutex_all_access, false, "Sam SP 44") = NULL)
  {
   // If no other process creates this mutex, recreate it.
   Hcounter = createmutex (null, false, "Sam SP 44 ");
  }

  // Create a thread
  Handle hthread [3];
  Cwinthread * pt1 = afxbeginthread (afx_threadproc) threada, (void *) 1 );
  Cwinthread * pt2 = afxbeginthread (afx_threadproc) threada, (void *) 2 );
  Cwinthread * pt3 = afxbeginthread (afx_threadproc) threada, (void *) 3 );
  Hthread [0] = pt1-> m_hthread;
  Hthread [1] = pt2-> m_hthread;
  Hthread [2] = pt3-> m_hthread;

  // Wait until the thread ends
  Waitformultipleobjects (3, hthread, true, infinite );

  // Close the handle
  Closehandle (hcounter );
 }
}

The waitforsingleobject function can act on:
Mutex
Event
Semaphore
Job
Process
Thread
Waitable Timer
Console input
Mutex, semaphore, and event can all be used by a process to synchronize data. Other objects have nothing to do with data synchronization, but for the process and thread, if the process and thread are in the running status, there is no signal, and there is a signal after exiting. So we can use waitforsingleobject to wait for the process and thread to exit. (As for traffic signals, the event usage will be discussed later) we used the waitformultipleobjects function in the previous example. This function is similar to waitforsingleobject, but we can see from the name that waitformultipleobjects
The function is used to wait for multiple objects to change to a signal state. The function prototype is as follows:
DWORD waitformultipleobjects (
 DWORD ncount,                   // Number of waiting objects
 Const handle * lphandles,// Object handle array pointer
 Bool fwaitall,                      // Waiting method,
 // If it is set to true, the system returns the result only when all objects are in the signal state. If it is set to false, the system returns the result when any object changes to the signal state.
 DWORD dwmilliseconds       // Timeout settings, in ms. If infinite is used, the waiting period is indefinite.
);

DwmillisecondsThe value range is from 0 to 0x7fffffff or infinite-0 xffffffff.

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.