使用临界区读取INI配置文件

本文介绍了Windows编程中使用CRITICAL_SECTION实现多线程同步的方法,通过示例展示了如何定义、初始化、进入和离开临界区。类BaseTool中定义了静态临界区变量用于保护共享资源,通过CLockHelper类实现了临界区的自动锁定和解锁,确保在读写INI配置文件时的安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     CRITICAL_SECTION 临界区,是一段独占对某些共享资源访问的代码,在任意时刻只允许一个线程对共享资源进行访问——达到用原子方式抢占共享资源
注意点:

CRITICAL_SECTION Critical; 定义临界区句柄,

EnterCriticalSection() 和 LeaveCriticalSection()函数去标识和释放一个临界;

CRITICAL_SECTION结构对象必须经过 InitializeCriticalSection()的初始化后才能使用
 

class BaseTool//抽象类(含有虚函数的类)
{
private:
	//	类内声明静态变量,定义临界区句柄,所有对象共享
	static CRITICAL_SECTION m_csSystemFileLock;
	static CRITICAL_SECTION m_csCommonFileLock;
public:
	CRITICAL_SECTION m_csLock;
	string m_strSystemFilePath;
	string m_strCommonFilePath;
	
	BaseTool();
	~BaseTool();

	virtual BOOL Init() = 0;
	virtual BOOL ReadParam() = 0;
	virtual BOOL WriteParam() = 0;

	//删除INI配置文件整个小节内容
	void DeleteIniSection(string IAppName, eIniType type);
	//删除INI配置文件小节下关键字内容
	void DeleteIniKey(string IAppName, string lpKeyName,eIniType type);

	//写INI配置文件小节,关键字,值
	void WriteIniString(string IAppName, string lpKeyName, string value, eIniType type);
	

	//读取INI配置文件小节,关键字的值
	int ReadIniInt(string IAppName, string lpKeyName, int value, eIniType type);
	string ReadIniString(string IAppName, string lpKeyName, string value, eIniType type);
	
};

类内声明静态成员变量需要在类外定义

CRITICAL_SECTION BaseTool::m_csSystemFileLock;
CRITICAL_SECTION BaseTool::m_csCommonFileLock;

自定义标识和释放临界区方法类

//标识和释放临界区的方法类,同时修改资源时互锁
class CLockHelper
{
private:
	CRITICAL_SECTION *m_pcs;
public:
	CLockHelper(CRITICAL_SECTION *pcs)
	{
		m_pcs = pcs;
		EnterCriticalSection(m_pcs);
	}
	~CLockHelper()
	{
		LeaveCriticalSection(m_pcs);
		m_pcs = NULL;
	}
};

类外定义成员函数

void BaseTool::DeleteIniSection(string IAppName, eIniType type)//删除INI配置文件的整个[小节]内容
{
	CRITICAL_SECTION* pLk;
	string strFilePath;
	if (type == SystemFile)
	{
		pLk = &m_csSystemFileLock;	
		strFilePath = m_strSystemFilePath;
	}
	else
	{
		pLk = &m_csCommonFileLock;
		strFilePath = m_strCommonFilePath;
	}
	SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);//设置文件属性
	CLockHelper lk(pLk);
	WritePrivateProfileString(IAppName.c_str(), NULL, NULL, strFilePath.c_str());
}

void BaseTool::DeleteIniKey(string IAppName, string lpKeyName, eIniType type)
{
	CRITICAL_SECTION* pLk;
	string strFilePath;
	if (type == SystemFile)
	{
		pLk = &m_csSystemFileLock;
		strFilePath = m_strSystemFilePath;
	}
	else
	{
		pLk = &m_csCommonFileLock;
		strFilePath = m_strCommonFilePath;
	}
	SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);
	CLockHelper lk(pLk);
	WritePrivateProfileString(IAppName.c_str(), lpKeyName.c_str(), NULL, strFilePath.c_str());
}

void BaseTool::WriteIniString(string IAppName, string lpKeyName, string value, eIniType type)//INI配置文件依据小节名字插入关键字和值
{
	CRITICAL_SECTION* pLk;
	string strFilePath;
	if (type == SystemFile)
	{
		pLk = &m_csSystemFileLock;
		strFilePath = m_strSystemFilePath;
	}
	else
	{
		pLk = &m_csCommonFileLock;
		strFilePath = m_strCommonFilePath;
	}
	SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);//设置文件属性

	//方案1 使用的类的构造和析构函数来标识和释放临界区
	CLockHelper lk(pLk);//程序运行到此处执行CLockHelper构造函数,待执行完WritePrivateProfileString后执行CLockHelper的析构函数
	WritePrivateProfileString(IAppName.c_str(), lpKeyName.c_str(), value.c_str(), strFilePath.c_str());
	//方案2  直接使用函数标识和释放临界区
	EnterCriticalSection(pLk);
	WritePrivateProfileString(IAppName.c_str(), lpKeyName.c_str(), value.c_str(), strFilePath.c_str());
	LeaveCriticalSection(pLk);
}

string BaseTool::ReadIniString(string IAppName, string lpKeyName, string value, eIniType type)//依据小节和关键字读取INI配置文件的关键字的值
{
	CRITICAL_SECTION* pLk;
	string strFilePath;
	if (type == SystemFile)
	{
		pLk = &m_csSystemFileLock;
		strFilePath = m_strSystemFilePath;
	}
	else
	{
		pLk = &m_csCommonFileLock;
		strFilePath = m_strCommonFilePath;
	}
	SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);//设置文件属性
	CLockHelper lk(pLk);
	char strRead[1024];
	GetPrivateProfileString(IAppName.c_str(), lpKeyName.c_str(), value.c_str(), strRead, MAX_PATH,strFilePath.c_str());
	return strRead;
}

int BaseTool::ReadIniInt(string IAppName, string lpKeyName,int value, eIniType type)//依据小节和关键字读取INI配置文件的关键字的值
{
	CRITICAL_SECTION* pLk;
	string strFilePath;
	if (type == SystemFile)
	{
		pLk = &m_csSystemFileLock;
		strFilePath = m_strSystemFilePath;
	}
	else
	{
		pLk = &m_csCommonFileLock;
		strFilePath = m_strCommonFilePath;
	}
	SetFileAttributes(strFilePath.c_str(), FILE_ATTRIBUTE_NORMAL);//设置文件属性
	CLockHelper lk(pLk);
	return(GetPrivateProfileInt(IAppName.c_str(), lpKeyName.c_str(), value, strFilePath.c_str()));
}

类外定义构造函数和析构函数, 并对临界区句柄进行InitializeCriticalSection()的初始化

BaseTool::BaseTool()
{
	//初始化临界对象
	InitializeCriticalSection(&m_csLock);
	InitializeCriticalSection(&m_csSystemFileLock);
	InitializeCriticalSection(&m_csCommonFileLock);

	m_strSystemFilePath="D://Test/Run-x64/Config/System.vis";
	m_strCommonFilePath = "D://Test/Run-x64/Config/Common.dh";
}

BaseTool ::~BaseTool()
{

}

继承抽象类,实现抽象类方法,并进行此类的主要功能

class Detect :public BaseTool//这个类继承基础工具类,主函数处调用此对象方法即可实现多个对象对同一配置文件的操作
{
public:
	BOOL Init() { return TRUE; }
	BOOL ReadParam() { return TRUE; }
	BOOL WriteParam() {return TRUE; }
};

程序入口,此处为mian()函数,通常在程序入口通过派生类实现读写操作

int main()//正常情况下应该是某个类的运行函数,在主入口处调用
{
	Detect temp;
	temp.DeleteIniSection("Product", SystemFile);//删
	temp.WriteIniString("Product1", "Count","7", SystemFile);//增
	temp.WriteIniString("Product1", "Type", "normal", SystemFile);

	int a;
	a=temp.ReadIniInt("Product1", "Count", 10, SystemFile);//查
	cout << a << endl;
	string b;
	b = temp.ReadIniString("Product1", "Type", "double", SystemFile);
	cout << b << endl;
	int c;
	cin >> c;

	return 0;
}

运行结果

编译后台

 配置文件内容

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值