Multi-thread critical area programming

Source: Internet
Author: User

I. implementation technologies are as follows:

1. manage resources with objects (for example, critical zones), that is, resources are obtained and initialized (raiI ).

2. prevent exceptions from escaping from the destructor, that is, exceptions generated by the Destructor must be captured.

3. thread security is sufficient.

Ii. Object-based resource management:

1. resource analysis not managed by objects:

The following uses the ccriticalsection class (see the source code in the appendix) as an example:

(A) This class can be used to manage critical zones. The specific functions are as follows:

<1> initialize the critical section (Init ()).

<2> lock () in the critical section ()).

<3> unlock () in the critical section ()).

<4> delete a critical section (term ()).

(B) The following are limitations of this class:

<1> the user may use the critical section before the critical section is initialized.

For example, locking, unlocking, or deleting the critical section before initialization will cause the program to crash.

<2> the user may continue to use the critical section after deleting the critical section.

For example, after the critical section is deleted, lock or unlock the critical section, which causes the program to crash.

<3> the user may forget to delete the critical section that is no longer in use.

For example, if you forget to delete it after the critical section is no longer used, memory leakage occurs.

<4> after the user locks the critical section, the user may forget to unlock it or the program may have an exception before unlocking. This may cause the critical section to remain locked, this prevents other users from accessing the locked data in the critical section, which also results in Memory leakage that cannot be deleted in the critical section.

2. Object-based resource management analysis:

(A) Take the cautocriticalsection class (see Appendix Source Code) for example:

This class can implement the ccriticalsection function and overcome its shortcomings.

This class has the following advantages:

<1> ensure that the critical section is initialized before the critical section is used.

The technology used is: resource acquisition is initialized, that is, the critical section is initialized in the constructor of this class.

<2> Memory leakage will not occur because the user forgets to delete the critical section.

Implementation Method: Delete the unused critical section in the destructor of the function.

<3> after you delete a critical section, the critical section is no longer used.

Implementation Method: Before using a critical section, determine whether the critical section still exists. If so, you can continue to use it. If not, you can stop using it.

(B) Take the cobjectlockt class (for the source code, see the appendix) for example:

This class can manage the cautocriticalsection class, so as to prevent the danger of forgetting to unlock.

Implementation Method: locks the critical section in the constructor of this class and unlocks the critical section in the destructor.

Cause: the destructor of the Class Object is called when the scope of the Class Object is left or an exception occurs. Therefore, the unlock of the dry critical section can be ensured.

Iii. destructor and exceptions

1. The Destructor does not capture exceptions.

When the Destructor generates an exception, if the capture does not have the capture time at this time, the program will crash and the cause of the program crash will not be understood.

2. Capture exceptions in destructor

Exceptions must be caught in the destructor. When exceptions occur, you can write down the cause of the exceptions and terminate the program normally.

3. Reasons for external provision of the term () function

Since the Destructor calls this function, what is the reason for providing this function externally?

<1> you can delete a critical section at any time to save memory usage.

<2> the purpose of this function is to give the user a chance to handle errors. If the user thinks that the function will not produce exceptions or errors, if an error or exception occurs when the Destructor calls the function, the user cannot complain that we have no chance to handle the error.

Iv. Thread Security

You can pass different classes (cmultithreadmodel and csinglethreadmodel) to the cobjectrootex template class to ensure thread security control.

1. Use the csinglethreadmodel class as the template parameter of the cobjectrootex class.

When locking a client program, that is, calling lock (), the final call is lock () of the cfakecriticalsection class. The lock of this class is not implemented and is just a simple return. The same is true for unlocking.

2. Use the cmultithreadmodel class as the template parameter of the cobjectrootex class.

When the customer's program is locked, that is, when the lock () is called, the lock () of the ccriticalsection class is finally called to lock the critical section, it can prevent concurrent access by multiple threads. The same is true for unlocking.

Summary:

1. If you are sure that your program is not running in a multi-threaded environment, you can make your program inherit the cobjectrootex class and take the csinglethreadmodel class as a parameter. This may seem redundant now.

2. If your program runs in a multi-line environment one day, you only need to replace the csinglethreadmodel class with the cmultithreadmodel class. Nothing else needs to be changed, this allows the thread to synchronously access public data.

 

 

 

Appendix:

//////////////////////////////////////// /////////////

// Asynchronous code

//////////////////////////////////////// ////////////

# Ifndef asyn_h _

# Define asyn_h _

Class ccriticalsection

{

Public:

Ccriticalsection () Throw ()

{

Memset (& m_sec, 0, sizeof (critical_section ));

}

Virtual ~ Ccriticalsection ()

{

}

Hresult lock () Throw ()

{

Entercriticalsection (& m_sec );

Return s_ OK;

}

Hresult unlock () Throw ()

{

Leavecriticalsection (& m_sec );

Return s_ OK;

}

Hresult Init () Throw ()

{

Hresult hres = e_fail;

Try

{

Initializecriticalsection (& m_sec );

Hres = s_ OK;

}

Catch (...)

{

Hres = e_outofmemory;

}

Return hres;

}

Hresult term () Throw ()

{

Deletecriticalsection (& m_sec );

Return s_ OK;

}

PRIVATE:

Critical_section m_sec;

};

 

Class cautocriticalsection: Public ccriticalsection

{

Public:

Cautocriticalsection ()

: M_btermed (true)

{

Hresult hR = ccriticalsection: Init ();

If (failed (HR ))

{

Throw hr;

}

M_btermed = false;

}

~ Cautocriticalsection () Throw ()

{

Try

{

Term ();

}

Catch (...)

{

 

}

}

Hresult term () Throw ()

{

Hresult hres = s_ OK;

If (! M_btermed)

{

M_btermed = true;

Hres = ccriticalsection: term ();

}

Return hres;

}

PRIVATE:

Hresult Init ();

PRIVATE:

Bool m_btermed;

};

Class csafedeletecriticalsection: Public ccriticalsection

{

Public:

Csafedeletecriticalsection ()

: M_binitialized (false)

{

}

~ Csafedeletecriticalsection () Throw ()

{

Try

{

Term (); // derived class

}

Catch (...)

{

// Log

}

}

Hresult Init () Throw ()

{

Hresult hR = ccriticalsection: Init ();

If (succeeded (HR ))

{

M_binitialized = true;

}

Return hr;

}

Hresult term () Throw ()

{

Hresult hres = s_ OK;

If (m_binitialized)

{

M_binitialized = false;

Hres = ccriticalsection: term ();

}

Return hres;

}

Hresult lock () Throw ()

{

Hresult hres = s_ OK;

If (m_binitialized)

{

Hres = ccriticalsection: Lock ();

}

Return hres;

}

Hresult unlock () Throw ()

{

Hresult hres = s_ OK;

If (m_binitialized)

{

Hres = ccriticalsection: Unlock ();

}

Return hres;

}

PRIVATE:

Bool m_binitialized;

};

 

Class cfakecriticalsection

{

Public:

Hresult lock () Throw () {return s_ OK ;}

Hresult unlock () Throw () {return s_ OK ;}

Hresult Init () Throw () {return s_ OK ;}

Hresult term () Throw () {return s_ OK ;}

};

 

Class cmultithreadmodel

{

Public:

Typedef cautocriticalsection autodeletecriticalsection;

};

 

Class csinglethreadmodel

{

Public:

Typedef cfakecriticalsection autodeletecriticalsection;

};

 

// Foward Declaration

Template <typename threadmodel>

Class cobjectlockt;

 

Template <typename threadmodel>

Class cobjectrootex

{

Public:

Typedef typename threadmodel: autodeletecriticalsection _ autodelcritsec;

Typedef cobjectlockt <threadmodel> objectlock;

Public:

Void lock ()

{

M_critsec.lock ();

}

Void unlock ()

{

M_critsec.unlock ();

}

PRIVATE:

_ Autodelcritsec m_critsec;

};

 

Template <typename threadmodel>

Class cobjectlockt

{

Public:

Cobjectlockt (cobjectrootex <threadmodel> * P)

: M_p (P)

, M_bunlocked (false)

{

If (m_p)

{

M_p-> lock ();

}

}

~ Cobjectlockt ()

{

Try

{

Term ();

}

Catch (...)

{

// Prevent exception leak out from Deconstruction

}

}

 

Void term () Throw ()

{

If (! M_bunlocked)

{

If (m_p)

{

M_p-> unlock ();

}

M_bunlocked = true;

}

}

PRIVATE:

Cobjectlockt (const cobjectlockt &);

Cobjectlockt & operator = (const cobjectlockt &);//

PRIVATE:

Cobjectrootex <threadmodel> * m_p;

Bool m_bunlocked;

};

 

# Endif

 

 

//////////////////////////////////////// //

/// The following is the test code.

# Include <iostream>

# Include <windows. h>

# Include "Asyn. H"

Using namespace STD;

//////////////////////////////////////// ///////////////////////////

/// Test code

//////////////////////////////////////// //////////////////////////

Class ctestclass

: Public cobjectrootex <csinglethreadmodel> // test not asynchronous

//: Public cobjectrootex <cmultithreadmodel> // test asynchronous

{

Public:

Void testfunc ();

};

Void ctestclass: testfunc ()

{

Objectlock clobjectlock (this); // lock

Cout <"ctestclass: testfunc come in" <Endl;

/// Other code

/// Your data does't be visited by multithread at the same time.

Sleep (3000); // test lock

Cout <"sleep over" <Endl;

}

 

 

Ctestclass clctestclass;

DWORD threadproc (

Lpvoid lpparameter

)

{

Clctestclass. testfunc (); // test thread visit

Return 0;

}

Void main ()

{

DWORD dwthreadid = 0;

Createthread (null, 0, (lpthread_start_routine) & threadproc, null, 0, & dwthreadid );

Clctestclass. testfunc (); // main thread visit

Sleep (5000 );

}

 

This article from the csdn blog, source: http://blog.csdn.net/firststudy/archive/2009/03/01/3946294.aspx

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.