线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的使用方法
注:使用结构CRITICAL_SECTION 需增加头文件#include “afxmt.h”
定义一个全局的锁 CRITICAL_SECTION的实例
和一个静态全局变量- CRITICAL_SECTION cs;//能够理解为锁定一个资源
- static int n_AddValue = 0;//定义一个静态的所有变量n_AddValue
创建两个线程函数,代码实现例如以下:
- //第一个线程
- UINT FirstThread(LPVOID lParam)
- {
- EnterCriticalSection(&cs);//加锁 接下来的代码处理过程中不同意其它线程进行操作,除非遇到LeaveCriticalSection
- for(int i = 0; i<10; i++){
- n_AddValue ++;
- cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
- }
- LeaveCriticalSection(&cs);//解锁 到EnterCriticalSection之间代码资源已经释放了,其它线程能够进行操作
- return 0;
- }
- //第二个线程
- UINT SecondThread(LPVOID lParam)
- {
- EnterCriticalSection(&cs);//加锁
- for(int i = 0; i<10; i++){
- n_AddValue ++;
- cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
- }
- LeaveCriticalSection(&cs);//解锁
- return 0;
- }
在主函数加入下面代码
- int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
- {
- int nRetCode = 0;
- // 初始化 MFC 并在失败时显示错误
- if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
- {
- // TODO: 更改错误代码以符合您的须要
- _tprintf(_T("错误: MFC 初始化失败/n"));
- nRetCode = 1;
- }
- else
- {
- InitializeCriticalSection(&cs);//初始化结构CRITICAL_SECTION
- CWinThread *pFirstThread,*pSecondThread;//存储函数AfxBeginThread返回的CWinThread指针
- pFirstThread = AfxBeginThread(FirstThread,LPVOID(NULL));//启动第一个线程
- pSecondThread = AfxBeginThread(SecondThread,LPVOID(NULL));//启动第二个线程
- HANDLE hThreadHandle[2];//
- hThreadHandle[0] = pFirstThread->m_hThread;
- hThreadHandle[1] = pSecondThread->m_hThread;
- //等待线程返回
- WaitForMultipleObjects(2,hThreadHandle,TRUE,INFINITE);
- }
- return nRetCode;
- }
输出:
n_AddValue in FirstThread is 1
n_AddValue in FirstThread is 2n_AddValue in FirstThread is 3n_AddValue in FirstThread is 4n_AddValue in FirstThread is 5n_AddValue in FirstThread is 6n_AddValue in FirstThread is 7n_AddValue in FirstThread is 8n_AddValue in FirstThread is 9n_AddValue in FirstThread is 10n_AddValue in SecondThread is 11n_AddValue in SecondThread is 12n_AddValue in SecondThread is 13n_AddValue in SecondThread is 14n_AddValue in SecondThread is 15n_AddValue in SecondThread is 16n_AddValue in SecondThread is 17n_AddValue in SecondThread is 18n_AddValue in SecondThread is 19n_AddValue in SecondThread is 20
假设把两个线程函数中的EnterCriticalSection和LeaveCriticalSection位置移到for循环中去,线程的运行顺序将会改变
输出也就跟着改变,如:- //第一个线程
- UINT FirstThread(LPVOID lParam)
- {
- for(int i = 0; i<10; i++){
- EnterCriticalSection(&cs);//加锁 锁移到for循环内部里
- n_AddValue ++;
- cout << "n_AddValue in FirstThread is "<<n_AddValue <<endl;
- LeaveCriticalSection(&cs);//解锁
- }
- return 0;
- }
- //第二个线程
- UINT SecondThread(LPVOID lParam)
- {
- for(int i = 0; i<10; i++){
- EnterCriticalSection(&cs);//加锁
- n_AddValue ++;
- cout << "n_AddValue in SecondThread is "<<n_AddValue <<endl;
- LeaveCriticalSection(&cs);//解锁
- }
- return 0;
- }
其它代码不变,输出的结果例如以下:
n_AddValue in FirstThread is 1
n_AddValue in SecondThread is 2n_AddValue in FirstThread is 3n_AddValue in SecondThread is 4n_AddValue in FirstThread is 5n_AddValue in SecondThread is 6n_AddValue in FirstThread is 7n_AddValue in SecondThread is 8n_AddValue in FirstThread is 9n_AddValue in SecondThread is 10n_AddValue in FirstThread is 11n_AddValue in SecondThread is 12n_AddValue in FirstThread is 13n_AddValue in SecondThread is 14n_AddValue in FirstThread is 15n_AddValue in SecondThread is 16n_AddValue in FirstThread is 17n_AddValue in SecondThread is 18n_AddValue in FirstThread is 19n_AddValue in SecondThread is 20
个人觉得在函数EnterCriticalSection和LeaveCriticalSection中间的代码运行过程不会被其它线程干拢或者这么讲不同意其它线程中
的代码运行。这样能够有效防止一个全局变量在两个线程中同一时候被操作的可能性