C++线程同步 CCRITICALSECTION(临界区类)附自己写的测试代码

C++线程同步 CCRITICALSECTION(临界区类)附自己写的测试代码当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。CCriticalSection类的用法如下:定义CCriticalSection类的一个全局对象(以使各个线

大家好,又见面了,我是你们的朋友全栈君。

当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。

CCriticalSection类的用法如下:
定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如CCriticalSection critical_section;
在访问需要保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象: critical_section.Lock();
在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线程占有临界区对象,则调用Lock()的线程获得临界区;否则,线程将被挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。
访问临界区完毕后,使用CCriticalSection的成员函数Unlock()来释放临界区: critical_section.Unlock();
再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会继续执行
其实我就是在网上搜了上面这段话,c++也是3天前才开始学的,对它的多线程也不了解。然后花了2小时来折腾,终于写出来了一个能够测试CCriticalSection的代码。
代码测试环境vs2008,win7

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// Win32ConsoleTest.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include
#include //vs2005以上版本都是这么写的
#include
#include
 
CCriticalSection MyCriticalSection;
//临界区类用来锁定线程对公用变量的访问
DWORD
WINAPI FunctionAdd(
LPVOID
lpParameter);
//thread data 一定要先声明
DWORD
WINAPI FunctionDeduct(
LPVOID
lpParameter);
//thread data
int
num=100;
//计数器
 
int
_tmain(
int
argc, _TCHAR* argv[])
{
HANDLE
hThread1;
HANDLE
hThread2;
//创建线程
hThread1=CreateThread(NULL,0,FunctionAdd,NULL,0,NULL);
hThread2=CreateThread(NULL,0,FunctionDeduct,NULL,0,NULL);
 
getch();
//按任意键退出
return
0;
}
 
DWORD
WINAPI FunctionAdd(
PVOID
arg)
//加法函数
{
while
(1)
{
MyCriticalSection.Lock();
num++;
printf
(
"执行了num++:%d\n"
,num);
MyCriticalSection.Unlock();
Sleep(100);
//注意这个Sleep一定要放到Lock锁外面,在Lock是不会释放线程的
}
}
 
DWORD
WINAPI FunctionDeduct(
PVOID
arg)
//减法函数
{
while
(1)
{
MyCriticalSection.Lock();
num--;
printf
(
"执行了num--:%d\n"
,num);
MyCriticalSection.Unlock();
Sleep(100);
}
}

说明FunctionAdd,FunctionDeduct都被得到了执行。如果我们把上面代码中的MyCriticalSection.Unlock();注释掉,则会出现全部是num++这种情况。调试跟踪发现不Unlock解锁则一直在FunctionAdd线程里面执行。这也是为什么Sleep()一定要放到Unlock()外面的原因。Lock()会占着线程不放,直到Unlock()

转载请注明http://www.duguxue.com/?p=317

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • jpg转nv12_jpeg改jpg

    jpg转nv12_jpeg改jpg代码主要用到了libyuv库和libjpeg库。编译:g++demo.cpp-lyuv-ljpeg-odemoubuntu下测试(需安装ffmpeg,width以及height按实际情况填写):ffplay-itest.yuv-pixel_formatnv12-swidthxheightdemo:#include<stdio.h>#include<stdlib.h>#include<libyuv.h>#..

    2022年9月16日
    2
  • ubuntu安装cuda和cudnn_ubuntu查看是否安装cuda

    ubuntu安装cuda和cudnn_ubuntu查看是否安装cuda目录1、查看系统推荐的cuda版本2、官网下载cuda软件包3、安装4、环境配置5、验证cuda是否正常1、查看系统推荐的cuda版本查看前应先安装显卡驱动,可以查看NVIDIA显卡驱动安装nvidia-smi这里显示的是cuda11.4版本2、官网下载cuda软件包官网cuda下载对应的cuda版本这里选择11.4.4的版本wgethttps://developer.download.nvidia.com/comput.

    2022年9月23日
    3
  • SQL中declare_hive变量赋值

    SQL中declare_hive变量赋值平时写SQL查询、存储过程都是凭着感觉来,没有探究过SQL的具体语法,一直都是按c#那一套往SQL上模仿,前几天项目中碰到一个问题引起了我对declare定义变量的作用域的兴趣。大家都知道c#中的局部变量,在if中如果我们定义一个变量的话他的作用到if结束为止,if外是不识别这个变量的,else里都不能使用,简单的写一下。

    2022年8月20日
    9
  • loadrunner11使用教程_loadrunner12

    loadrunner11使用教程_loadrunner12

    2022年10月9日
    4
  • 免费pac代理地址_pac网址怎么设置

    免费pac代理地址_pac网址怎么设置问题起因:最近上http://nipponcolors.com/没上去,什么DNS污染啥的都试过了,最后是改本地PAC才好使得,大家可以用全局先看一下解决办法:添加如下连两行代码即可…

    2022年10月9日
    3
  • 算术运算符——整数运算

    算术运算符——整数运算

    2022年3月12日
    35

发表回复

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

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