首页 > 其他分享 >MFC---多线程(线程同步之关键代码段)

MFC---多线程(线程同步之关键代码段)

时间:2024-01-16 16:31:29浏览次数:26  
标签:NULL FALSE InitializeCriticalSection 代码段 --- 临界 cs 多线程


关键代码段,也称为临界区,工作在用户方式下。它是指一个小代码段,在代码能够执行前,它必须独占对某些资源的访问权。通常把多线程中访问同一种资源的那部分代码当做关键代码段。

1. 初始化关键代码段

调用InitializeCriticalSection函数初始化一个关键代码段。

InitializeCriticalSection(
    _Out_ LPCRITICAL_SECTION lpCriticalSection
    );

该函数只有一个指向CRITICAL_SECTION结构体的指针。在调用InitializeCriticalSection函数之前,首先需要构造一个CRITICAL_SCTION结构体类型的对象,然后将该对象的地址传递给InitializeCriticalSection函数。

2进入关键代码段

VOID
WINAPI
EnterCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );

调用EnterCriticalSection函数,以获得指定的临界区对象的所有权,该函数等待指定的临界区对象的所有权,如果该所有权赋予了调用线程,则该函数就返回;否则该函数会一直等待,从而导致线程等待。

3.退出关键代码段

VOID
WINAPI
LeaveCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection);
线程使用完临界区所保护的资源之后,需要调用LeaveCriticalSection函数,释放指定的临界区对象的所有权。之后,其他想要获得该临界区对象所有权的线程就可以获得该所有权,从而进入关键代码段,访问保护的资源。

4.删除临界区

WINBASEAPI
VOID
WINAPI
DeleteCriticalSection(
    _Inout_ LPCRITICAL_SECTION lpCriticalSection
    );
当临界区不再需要时,可以调用DeleteCriticalSection函数释放该对象,该函数将释放一个没有被任何线程所拥有的临界区对象的所有资源。
BOOL COneIPCChannel::InitIPCChannel(CWnd * pVideoWnd)
{
	m_pVideoBuffer = new CVideoRecieveBuffer;
	m_pVideoWnd = pVideoWnd;
	m_bPlaying = FALSE;
	m_isTFPlay=FALSE;
	InitializeCriticalSection(&m_cs);
	m_hWaitEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

	return TRUE;
}

BOOL COneIPCChannel::InitIPCChannelREMOTE(CWnd * pVideoWnd,int *Session)
{
	m_Session=Session;
	m_pVideoWnd = pVideoWnd;
	m_bPlaying = FALSE;
	m_isTFPlay = FALSE;
	m_pVideoBuffer = new CVideoRecieveBuffer;
	InitializeCriticalSection(&m_cs);
	m_hWaitEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
	return TRUE;
}

卖票系统

#include <stdio.h>
#include <windows.h>
#include <process.h> 


int iTickets = 5000;
CRITICAL_SECTION g_cs;

// A窗口     B窗口

DWORD WINAPI SellTicketA(void* lpParam)
{
	while (1)
	{
		EnterCriticalSection(&g_cs);//进入临界区
		if (iTickets > 0)
		{
			Sleep(1);
			iTickets--;
			printf("A remain %d\n", iTickets);
			LeaveCriticalSection(&g_cs);//离开临界区
		}
		else
		{
			LeaveCriticalSection(&g_cs);//离开临界区
			break;
		}
	}
	return 0;
}

DWORD WINAPI SellTicketB(void* lpParam)
{
	while (1)
	{
		EnterCriticalSection(&g_cs);//进入临界区
		if (iTickets > 0)
		{
			Sleep(1);
			iTickets--;
			printf("B remain %d\n", iTickets);
			LeaveCriticalSection(&g_cs);//离开临界区
		}
		else
		{
			LeaveCriticalSection(&g_cs);//离开临界区
			break;
		}
	}
	return 0;
}


int main()
{
	HANDLE hThreadA, hThreadB;
	hThreadA = CreateThread(NULL, 0, SellTicketA, NULL, 0, NULL);  //2
	hThreadB = CreateThread(NULL, 0, SellTicketB, NULL, 0, NULL);  //2
	CloseHandle(hThreadA); //1
	CloseHandle(hThreadB); //1
	InitializeCriticalSection(&g_cs); //初始化关键代码段
	Sleep(40000);
	DeleteCriticalSection(&g_cs);//删除临界区
	system("pause");

	return 0;
}


标签:NULL,FALSE,InitializeCriticalSection,代码段,---,临界,cs,多线程
From: https://blog.51cto.com/u_15305087/9273794

相关文章

  • 方法论:仓储物流规划--数据分析(转)
     老K-LaoK专栏同名微信公众号:智能仓储物流技术研习社。​关注他 8人赞同了该文章导语大家好,我是智能仓储物流技术研习社的社长,你的老朋友,老K。知识星球 * 原创电子书 * 深海社区 * 微信群文:尹军琪在做物流规划设计时,人们往往对设计指标......
  • Unity FaceBook SDK - 1
    SDK下载前往https://developers.facebook.com/docs/unity/downloads下载SDKps目前我只用过16.0.0跑通 在facebook上搞出应用后,将应用的app相对于数据复制过来如图下: 安卓的话将上面的三个内容复制到facebook,然后点击一下按钮,生成出manifest 然后可以参考使......
  • svg使用封装-vue
    我们在项目中经常会使用到svg,这里对svg进行封装,以方便后续的使用。1.安装svg插件npmivite-plugin-svg-icons2.在vite.config.ts中引入,用来指定svg存放位置import{createSvgIconsPlugin}from"vite-plugin-svg-icons";import{resolve}from"path";constplugin......
  • AD采集卡设计方案:630-基于PCIe的高速模拟AD采集卡
     基于PCIe的高速模拟AD采集卡一、产品概述   基于PCIe的一款分布式高速数据采集系统,实现多路AD的数据采集,并通过PCIe传输到存储计算服务器,实现信号的分析、存储。    产品固化FPGA逻辑,适配2路1Gsps/2路2Gsps采集,实现PCIe的触发采集,单次采集容量2G......
  • (vcpu-0)Exception 0xc0000005 (access violation) has occurred
    VM安装window10报错如何解决?(vcpu-0)Exception0xc0000005(accessviolation)hasoccurred.(vcpu-1)Exception0xc0000005(accessviolation)hasoccurred.除了常规的虚拟化的一些原因外,如果网上的方式你都试过了,不能解决的话;那么请升级你的VMware到16.2.*版本即可;......
  • docker - 将几个目录复制到另一个目录
    您如何将多个目录复制到Docker中的目标目录?我不想复制目录内容,而是复制整个目录结构。COPY和ADD命令复制目录内容,展平结构,这是我不想要的。也就是说,如果这些是我的来源:.├──a│  ├──aaa.txt│  └──uuu.txt├──b│  ├──ooo.txt│  └──p......
  • [cpp]: operator""s -- <string>
    [cpp]: operator""s -- <string>    1operator""s:将一个字符数组字面量转化为【basic_string】类型数据。1.1#include<string>1.2operator""s :convertsacharacterarrayliteralto basic_string   2e.g.......
  • 无涯教程-SQL - Transactions(事务)
    事务是将一个或多个更改打包在一起保存到数据库,事务对于确保数据完整性和处理数据库错误很重要。事务性质事务具有以下四个标准属性,通常以首字母缩写ACID表示。原子性-确保工作单元内的所有操作均成功完成,否则,事务将在失败时中止,并且所有先前的操作都将还原到以前的状态......
  • 高速视频采集卡设计方案:620-基于PCIe的高速视频采集卡
    一、产品概述   基于PCIe的高速视频采集卡,通过PCIe3.0X8传输到存储计算服务器,实现信号的分析、存储。    北京太速科技产品固化FPGA逻辑,适配视频连续采集,缓存容量2GB,开源的PCIe QT客户端软件,用户可以在很短的时间内完成视频程序的开发,开发效率高、难度小。  ......
  • Linux--修改会话超时时间
    控制用户在一段时间内没有活动时会话的自动注销时间 1、修改ssh配置文件(适用于SSH会话)vim/etc/ssh/sshd_configClientAliveInterval1800#秒ClientAliveCountMax0#次数#更新配置sudosystemctlreloadsshd 2、修改终端环境变量(适用于交互式终端会话)用户......