First, Events:
CEvent class:
- declaration in header file Afxmt.h
- Whether the non-sending status can be automatically recovered according to the event object is divided into automatic event object and manual event object.
- The constructor functions are as follows:
1 CEvent (2 3BOOL Binitiallyown = FALSE,//false not sent, prevents the system from starting running the waiting thread4 5BOOL bManualReset = FALSE,//false Automatic Sending6LPCTSTR LpszNAme =NULL,7 8Lpsecurity_attributes Lpsaattribute =NULL9 Ten);
Note:
Automatic Sending--Initial state false(not sent), when needed, the CEvent member function setevent can be set to the sending State so that the first thread in the waiting thread queue resumes running, but the event object automatically turns its state to false. Automatic Event Objectonly one can be started at a timeThe thread that is waiting.
Manual-Manual Event object, once the function is set to "TRUE" to send the state, it has been in a valid state. Unless you reset it to FALSE by using the object's member function plusevent or resetevent. Therefore, it can be usedRecover multipleThe thread that is in the waiting state runs.
For example, the application of an automatic event object
Program Main function Description:
Click Start Thread, will start two threads, both pop up the message box, the machine is determined, the thread is itself suspended, and then the single SetEvent button, set to the sending State. Restart the thread sequentially.
The program is written using MFC dialog box program, the main function code is as follows:
/************************************************************************//*Global Event Object*//************************************************************************/CEvent g_eventobj;/************************************************************************//*as a child thread*//************************************************************************/UINT MsgThread1 (lpvoid pparam) {LPCWSTR PMSG=(LPCWSTR) Pparam; CWnd* Pmainwin =AfxGetMainWnd (); :: MessageBox (Pmainwin->m_hwnd, PMSG, _t ("Thread1 Message"), MB_OK); _t () is a macro, g_eventobj.lock (); //leave this thread in a wait statePMSG= _t ("Thread1 is unlocked"); :: MessageBox (Pmainwin->m_hwnd, PMSG, _t ("Thread1 Message"), MB_OK); G_eventobj.lock (); //leave this thread in a wait statePMSG= _t ("Thread1 is unlocked again"); :: MessageBox (Pmainwin->m_hwnd, PMSG, _t ("Thread1 Message"), MB_OK); return 0;}//Sub-thread 2UINT MsgThread2 (lpvoid pparam) {LPCWSTR PMSG=(LPCWSTR) Pparam; CWnd* Pmainwin =AfxGetMainWnd (); :: MessageBox (Pmainwin->m_hwnd, PMSG, _t ("Thread2 Message"), MB_OK); G_eventobj.lock (); //leave this thread in a wait statePMSG= _t ("Thread2 is unlocked"); :: MessageBox (Pmainwin->m_hwnd, PMSG, _t ("Thread2 Message"), MB_OK); return 0;}//Sub-thread 3UINT MsgThread3 (lpvoid pparam) {g_eventobj.setevent (); //set the event to the sending State return 0;}/************************************************************************//*Start thread button message response*//************************************************************************/voidCthread1dlg::onbnclickedbuttonthead () {//TODO: Add control notification handler code hereAfxBeginThread (msgthread1,_t ("Thread1 is started") ); AfxBeginThread (MsgThread2, _t ("Thread2 is started"));}
Run the following procedure:
Manual Event object: Change the code that defines the event object to:
CEvent g_eventobj (false,true);
Second, the critical section
CCriticalSection class:
- Declared in the Afxmt.h header file
- Can only be used between different threads in the same process
- Used to protect exclusive resources, such as printers. Only one thread is allowed to occupy a common resource.
- Its object is called the critical section , like a key, only to obtain it, the thread has the right to obtain resources and run.
- Its constructor has no arguments.
- !! It is important to note that the Lock () and unlock () member functions must be paired. Typically, the thread begins with lock exclusive resources, and when the thread ends, it uses unlock to unlock the resource for use by other threads.
Example program:
/************************************************************************//*Critical Segment*//************************************************************************/CCriticalSection g_criticalsection; //No parameters required/************************************************************************//*as a child thread*//************************************************************************/UINT msgthread (lpvoid pparam) {g_criticalsection.lock (); LPCWSTR PMSG=(LPCWSTR) Pparam; CWnd* Pmainwin =AfxGetMainWnd (); :: MessageBox (Pmainwin->m_hwnd, PMSG, L"Thread1 Message", MB_OK); G_criticalsection.unlock (); return 0;}//Sub-thread 2UINT MsgThread2 (lpvoid pparam) {g_criticalsection.lock (); LPCWSTR PMSG=(LPCWSTR) Pparam; CWnd* Pmainwin =AfxGetMainWnd (); :: MessageBox (Pmainwin->m_hwnd, PMSG, L"Thread2 Message", MB_OK); G_criticalsection.unlock (); return 0;}/************************************************************************//*Start thread button message response*//************************************************************************/voidCthread1dlg::onbnclickedbuttonthead () {//TODO: Add control notification handler code hereAfxBeginThread (msgthread,_t ("Thread1 is started") ); AfxBeginThread (MsgThread2, _t ("Thread2 is started"));}
Thread 1 obtains the critical segment first, and thread 2 runs after closing the message box created by thread 1.
Third, the mutex
CMutex class:
- Can be used in different processes
- In addition to the above, the rest and critical sections are basically the same.
- constructor function:
CMutex (
BOOL Binitiallyown = FALSE, // default Mutex status is non-locked
LPCTSTR lpszName = NULL, // Mutex name
Lpsecurity_attributes Lpsaattribute = NULL);
Iv. Signal Volume
CSemaphore class:
- Number of threads used to control access to shared resources
- There is a counter that can set the initial value, when using the member function lock, the counter value is reduced by one; Use unlock to add one. When the counter value is zero, other processes are prevented from accessing the shared resource.
- constructor function:
1, // Counter Initial value 1, // count Upper lpctstr pstrname= = NULL);
Example:
CSemaphore g_smph (2,3);//Counter Initial value = 2, upper =3/************************************************************************//*as a child thread*//************************************************************************/UINT msgthread (lpvoid pparam) {g_smph.lock (); LPCWSTR PMSG=(LPCWSTR) Pparam; CWnd* Pmainwin =AfxGetMainWnd (); :: MessageBox (Pmainwin->m_hwnd, PMSG, L"Thread1 Message", MB_OK); G_smph.unlock (); return 0;}/************************************************************************//*Start thread button message response*//************************************************************************/voidCthread1dlg::onbnclickedbuttonthead () {//You can create different threads multiple times with the same piece of codeAfxBeginThread (msgthread,_t ("Thread1 is started") ); AfxBeginThread (Msgthread, _t ("Thread2 is started")); AfxBeginThread (Msgthread, _t ("Thread3 is started")); AfxBeginThread (Msgthread, _t ("Thread4 is started"));}
Running Process: The program executes first, the process is the same. After closing one of the processes, execute Process 3, and then execute Process 4.
Note:
- The role of the _t () macro:
Ask:
#define ABC L "ABC"
What is macro used for, and is it related to Unicode?
If so, this and
#define ABC _t ("abc")
Is there a difference?
For:
L represents a Unicode string, such as wchar_t* str = L "YANGSONGX";
_t represents the ANSI string in ANSI compilation mode, and Unicode strings are represented under Unicode, such as
tchar* str = _t ("Yangsongx");
Compiling under ANSI is char* str = "YANGSONGX";
Compiling under Unicode is wchar_t* str = L "YANGSONGX";
MFC Thread Sync Beginner Notes