线程锁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)


相关推荐

  • stm32H747_mpeg4是什么格式和mp4

    stm32H747_mpeg4是什么格式和mp41.H.264与MPEG的关联 在视频编解码技术定义方面有两大标准机构。一个是国际电信联盟(ITU)致力于电信应用,已经开发了用于低比特率视频电话的H.26x标准,其中包括H.261、H.262、H.263与H.264;另一个是国际标准化组织(ISO)主要针对消费类应用,已经针对运动图像压缩定义了MPEG标准。MPEG标准包括MPEG1、MPEG2与MPEG4。 以制订国际通讯标准为主的国际电信联盟ITU-T,在完成H.263(针对视频会议之用的串流视频标准)后,与IS.

  • c语言必背100代码,初学者代码大全(c语言必背100代码)[通俗易懂]

    c语言必背100代码,初学者代码大全(c语言必背100代码)[通俗易懂]一个完全入门初学者如何学代码,读代码和写代码,,我想学代码不知道方向谁能给我指明一个方向?1、学代码:前提是你的复有一个比较系统的学习.认真完成每一个课程中的案例.2、读代码:分制两步走:前期能读懂自己写的代码.2113后期能读懂他人写的代码和大致的知道底层的某些源码的含义.多去5261看开发文档(开发文档建议使用官方提供的4102英文版、不要使用中文自己害自己)3、写代码1653:前提是你要有…

  • pytest指定用例_文件夹排列顺序自定义

    pytest指定用例_文件夹排列顺序自定义前言测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果.有些同学在写用例的时候,用例写了先后顺序,有先后顺序后,后面还会有新的问题(如:上个用例返回

  • RestTemplate设置MediaType[通俗易懂]

    RestTemplate设置MediaType[通俗易懂]Stringurl=”http://testurl”;Map<String,Object>requestMap=newHashMap<>();resultMap.put(“param1″,”value1”);resultMap.put(“param2″,”value2”);HttpHeadersheaders=newHttpH…

  • VS2017专业版使用最新版Qt5.9.2教程(最新教材)

    VS2017专业版使用最新版Qt5.9.2教程(最新教材)VS2017专业版使用最新版Qt5.9.2教程(最新教材)目录VS2017专业版使用最新版Qt5.9.2教程(最新教材)运行环境:1.安装Qt5.9.22.安装Qt5.9与VS2017之间的插件:3.配置QtVSTool的环境.4.设置创建的Qt的项目的属性,对包含目录、引用目录、库目录进行环境配置5.Qt的环境变量配置6.开心,开心,开心的样子,运行成功…

  • SSH学习笔记「建议收藏」

    SSH学习笔记「建议收藏」SSH学习笔记github主页:https://github.com/Taot-chen1、ssh(secureshell)安装:sudoapt-getinstallopenssh-server/openssh-client查看ssh服务是否开启:netstat-tlp|grepssh启动/重启/停止ssh服务:sudo/etc/init.d/ssdstart/restart/stop查看系统信息:cat/etc/os-release

发表回复

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

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