线程锁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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 谷歌与火狐Hackbar插件下载与安装

    谷歌与火狐Hackbar插件下载与安装谷歌与火狐Hackbar插件下载与安装首先下载Hackbar插件:https://github.com/Mr-xn/hackbar2.1.3将其中的压缩包拖拽到Chrome的扩展程序。点击详细信息在下面的“来源”处点击一个链接:会跳转到给插件在Chrome中安装的文件位置,打开hackbar-panel.js文件将三处disable_hackbar()函数替换成init(),保…

    2022年5月26日
    102
  • html5 canvas雨点打到窗玻璃动画

    html5canvas雨点打到窗玻璃动画HTML5下雨效果效果预览:http://hovertree.com/texiao/html5/4.htm以下是代码:1234567HTML5

    2021年12月21日
    43
  • 服务器安装gtx系列显卡驱动,win10装不上GTX1080显卡驱动怎么回事 win10安装不了gtx1080驱动现象的解决方案…

    服务器安装gtx系列显卡驱动,win10装不上GTX1080显卡驱动怎么回事 win10安装不了gtx1080驱动现象的解决方案…GTX1080装不上驱动怎么办?要问内部性能最强的电脑是什么?当然不是编辑们手上用的这些普通电脑啦,最强的性能当属我们的测试平台,i75960X加512G固态硬盘以及各式各样的顶级显卡,想想就让人流口水。但是最近这台超强的测试平台在重装系统后,遇到了一些小问题。下面脚本之家小编就给大家带来GTX1080装不上驱动解决办法。GeForceGTX1080测试平台重装完windows10系统之后…

    2022年5月18日
    63
  • mysql 5.6 安装(转)「建议收藏」

    mysql 5.6 安装(转)「建议收藏」mysql 5.6 安装(转)

    2022年4月22日
    51
  • vs2015激活成功教程密钥_vs2015产品激活密钥

    vs2015激活成功教程密钥_vs2015产品激活密钥对于开发者而言,一款优秀智能的开发工具能够提升应用开发的效率,正因为如此,VisualStudio作为主流的开发工具,微软非常的用心,不仅能够让这款开发工具满足用户体验的需要,同时能够支持更多的新技术架构,并且,VS2012更加适合用于开发Windows8专用程序。网上好多无效的,为了收藏,先保存一份。一、VS2012下载地址。中文版:http://download….

    2022年10月14日
    2
  • ftp扫描软件_ftp管理工具

    ftp扫描软件_ftp管理工具ftp扫描工具种类繁多,使用者就会在五花八门的软件里面去挑选自己最喜欢最适合的软件去使用。就是不知道大家是怎么选择的,小编的选择方式特别简单,就是好用的就成,简单快捷方便明了就可以了。所以要在这么多的扫描工具中去选择,该怎么去选择适合自己的ftp扫描软件呢?这边给你们整理了几个好用的ftp扫描工具。第一款:IIS7服务器管理工具这款软件里面的ftp扫描工具可谓是做的非常好的,内容全面又容易上手。适合新手也适合长期从事网站管理的工作人员。IIS7服务器管理工具里面的ftp扫描工具不仅具有批量管理的功能,还

    2022年9月30日
    2

发表回复

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

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