线程锁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);//若去掉此句 可能导致其他线程无法进入临界区
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 【转载】协程

    【转载】协程

    2021年11月18日
    47
  • 什么是句柄

    什么是句柄一、百度百科解释:在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(filehandle),该

    2022年7月1日
    21
  • PS学习总结三:修图必备的高阶操作

    PS学习总结三:修图必备的高阶操作目录一:滤镜二:滤镜下的一些操作三:智能对象四:通道五:通道抠图步骤六:裁剪工具七:修复工具八:仿制图章九:内容识别十:操作变形一:滤镜ps滤镜:主要通过各种命令来实现图像的各种特殊效果。智能滤镜优点:可编辑性强 有自带的蒙版,可以对局部进行处理 双击滤镜名称,修改滤镜参数 一个图层上可以添加多个滤镜效果cameraraw滤镜打开单反相机源文件格式cr2,那么回自动使用cameraraw滤镜打开。是摄影师后期专业的调色插件,他

    2022年6月16日
    34
  • 几种滤波算法,总结一下

    几种滤波算法,总结一下最近在做武术擂台,发现对于红外测距传感器的返回值速度很快,但是误差值很大,经过简单函数调校之后,发现还是有误差,有干扰数据,于是导入了math.h,进行的绝对值滤波,但是用循环暂存了十组数据,进行简单的加权算法,发现还是不行,于是去找了一些经典的滤波算法,算是简单记录一下。分享给大家。1、限幅滤波法(又称程序判断滤波法)A、方法:根据经验判断,确定两次采样允许…

    2022年5月1日
    39
  • windows 批处理 注释_vim批量注释

    windows 批处理 注释_vim批量注释一、Windows批处理添加注释使用::即可注释文字如图所示

    2025年5月29日
    4
  • java数据库图书销售系统_SQL+java数据库课程设计,图书销售管理系统[通俗易懂]

    java数据库图书销售系统_SQL+java数据库课程设计,图书销售管理系统[通俗易懂]【实例简介】SQL数据库课程设计,图书销售管理系统,报告,任务书,挺全的【实例截图】【核心代码】07计本2班_15号_刘思旭_图书销售管理系统└──07计本2班_15号_刘思旭_图书销售管理系统├──07计本2班_15号_刘思旭_图书销售管理系统│├──数据库││├──bookshop_Data.MDF││└──bookshop_Log.LDF│└──…

    2022年6月7日
    23

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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