Next, let's look at another method to achieve sequential access in the critical section.
This time, we use InitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection, and DeleteCriticalSection.
To use these variables, you must include windows. h and define a CRITICAL_SECTION variable.
So what is the difference between this method and the implementation of mutex in the previous article?
The following is the implementation code:
View Code
#pragma once#include <windows.h>#include <assert.h>class CVCriSection{public: CVCriSection(void); ~CVCriSection(void);public: int CsEnter() { EnterCriticalSection(&m_cs); return 0; } int CsLeave() { LeaveCriticalSection(&m_cs); return 0; }protected: CRITICAL_SECTION m_cs;};class CVCriSectionAuto{public: CVCriSectionAuto(CVCriSection* cs) { m_cs=cs; m_cs->CsEnter(); } ~CVCriSectionAuto(void) { m_cs->CsLeave(); m_cs=NULL; }private: CVCriSection* m_cs;};CVCriSection::CVCriSection(void){ InitializeCriticalSection(&m_cs);}CVCriSection::~CVCriSection(void){ DeleteCriticalSection(&m_cs);}
The following test code is available:
Cvcriection cs; int sum = 0; int last = 0; pthread_mutex_t g_mutex = CreateMutex (NULL, FALSE, NULL); dword winapi worker (LPVOID lpParameter) {int no = (int) lpParameter; last = no; while (1) {cvcriectionauto csauto (& cs); // method 1 // CCriticalSection cs (g_mutex); // method 2, in this way, it will strictly follow 0, 1, 2, 0, 1, 2 .... or 1, 0, 2, 1, 0, 2, and so on, both three threads have equal running opportunities // cs. csEnter (); sum = 0; for (int I = 0; I <= 100000; I ++) sum + = I; if (no! = (Last + 1) % 3) printf ("not equal \ n"); last = no; // cs. csLeave () ;}} int main () {for (int I = 0; I <3; I ++) CreateThread (NULL, 0, worker, (LPVOID) I, 0, NULL); Sleep (20000); return 0 ;}
When method 1 (implemented using CRITICAL_SECTION) is used to achieve mutex access, the above Code will have a lot of not equal output. This means that the number of execution times of the three threads is random.
When method 2 is used to achieve mutex access, the above Code will not have not equal output. That is to say, the three threads have an equal running opportunity. The number of times they access the critical section is equivalent.
The following test code shows their differences more intuitively:
Cvcriection cs; int sum = 0; int last = 0; int cnt [3] = {0, 0, 0}; pthread_mutex_t g_mutex = CreateMutex (NULL, FALSE, NULL ); dword winapi worker (LPVOID lpParameter) {int no = (int) lpParameter; last = no; while (1) {// cvcriectionauto csauto (& cs ); // method 1 CCriticalSection cs (g_mutex); // method 2, which strictly follows 0, 1, 2, 0, 1, 2 .... or 1, 0, 2, 1, 0, 2, and so on, both three threads have equal running opportunities // cs. csEnter (); sum = 0; for (int I = 0; I <= 100000; I ++) sum + = I; cnt [no] ++; // cs. csLeave () ;}} int main () {for (int I = 0; I <3; I ++) CreateThread (NULL, 0, worker, (LPVOID) I, 0, NULL); Sleep (5000); for (int j = 0; j <3; j ++) printf ("% d \ n", cnt [j]); return 0 ;}
Finally, output the number of times three threads enter the critical section respectively.
Summary:
With the implementation of CRITICAL_SECTION, the number of times the thread accesses the critical zone is basically proportional to the speed at which the thread executes.
With the implementation of mutex, the number of threads accessing the critical zone is basically equal.
Select an appropriate method based on the actual scenario.
The following code can be used to verify the above conclusion.
View Code
Cvcriection cs; int sum = 0; int last = 0; int cnt [3] = {0, 0, 0}; pthread_mutex_t g_mutex = CreateMutex (NULL, FALSE, NULL ); dword winapi worker (LPVOID lpParameter) {int no = (int) lpParameter; last = no; while (1) {cvcriectionauto csauto (& cs ); // method 1 // CCriticalSection cs (g_mutex); // method 2, which strictly follows 0, 1, 2, 0, 1, 2 .... or 1, 0, 2, 1, 0, 2, and so on, both three threads have equal running opportunities // cs. csEnter (); sum = 0; int add = no * 1000; for (int I = 0; I <= 10000 + add; I ++) sum + = I; cnt [no] ++; // cs. csLeave () ;}} int main () {for (int I = 0; I <3; I ++) CreateThread (NULL, 0, worker, (LPVOID) I, 0, NULL); Sleep (5000); for (int j = 0; j <3; j ++) printf ("% d \ n", j, cnt [j]); return 0 ;}