线程锁EnterCriticalSection和LeaveCriticalSection的用法

线程锁EnterCriticalSection和LeaveCriticalSection的用法线程锁的概念函数EnterCriticalSection和LeaveCriticalSection的用法注:使用结构CRITICAL_SECTION需加入头文件#include“afxmt.h”定义一个全局的锁CRITICAL_SECTION的实例  和一个静态全局变量CRITICAL_SECTIONcs;//可以理解为锁定一个资源staticintn_AddVal

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

线程锁的概念函数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);
}
DeleteCriticalSection(&cs);//删除临界区
return nRetCode;
}
输出:
n_AddValue in FirstThread is 1

  n_AddValue in FirstThread is 2

  n_AddValue in FirstThread is 3

  n_AddValue in FirstThread is 4

  n_AddValue in FirstThread is 5

  n_AddValue in FirstThread is 6

  n_AddValue in FirstThread is 7

  n_AddValue in FirstThread is 8

  n_AddValue in FirstThread is 9

  n_AddValue in FirstThread is 10

  n_AddValue in SecondThread is 11

  n_AddValue in SecondThread is 12

  n_AddValue in SecondThread is 13

  n_AddValue in SecondThread is 14

  n_AddValue in SecondThread is 15

  n_AddValue in SecondThread is 16

  n_AddValue in SecondThread is 17

  n_AddValue in SecondThread is 18

  n_AddValue in SecondThread is 19

  n_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 2

  n_AddValue in FirstThread is 3

  n_AddValue in SecondThread is 4

  n_AddValue in FirstThread is 5

  n_AddValue in SecondThread is 6

  n_AddValue in FirstThread is 7

  n_AddValue in SecondThread is 8

  n_AddValue in FirstThread is 9

  n_AddValue in SecondThread is 10

  n_AddValue in FirstThread is 11

  n_AddValue in SecondThread is 12

  n_AddValue in FirstThread is 13

  n_AddValue in SecondThread is 14

  n_AddValue in FirstThread is 15

  n_AddValue in SecondThread is 16

  n_AddValue in FirstThread is 17

  n_AddValue in SecondThread is 18

  n_AddValue in FirstThread is 19

  n_AddValue in SecondThread is 20
个人认为在函数EnterCriticalSection和LeaveCriticalSection中间的代码执行过程不会被其他线程干拢或者这么讲不允许其他线程中

  的代码执行。这样可以有效防止一个全局变量在两个线程中同时被操作的可能性
[2]
 
使用EnterCriticalSection与LeaveCriticlSection时应注意
若在同一个线程中第一次LeaveCriticlSection与第二次EnterCriticalSection执行间隔较短(如一个循环内的最后一行与第一行),可能导致其他线程无法进入临界区。此时可在LeaveCriticlSection后适当延时。
DWORD WINAPI ThreadProc2(LPVOID lpParameter)
{
for(;;)
{
EnterCriticalSection(&cs);
cout << “In ThreadProc2” << endl;
LeaveCriticalSection(&cs);
Sleep(100);//若去掉此句 可能导致其他线程无法进入临界区
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/192883.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号