gpt4 book ai didi

c++ - 关于CRITICAL_SECTION的使用问题

转载 作者:太空狗 更新时间:2023-10-29 23:47:29 24 4
gpt4 key购买 nike

给定以下代码,

class MyCriticalSection : protected CRITICAL_SECTION
{
public:
MyCriticalSection()
{
InitializeCriticalSection(this);
EnterCriticalSection(this);
}
~MyCriticalSection()
{
LeaveCriticalSection(this);
DeleteCriticalSection(this);
}
};

class MyClass
{
public:
MyClass() : m_Int(0) {}

int GetNum()
{
MyCriticalSection myCriticalSectionA; // LockA

return m_Int;
}

int SetNum(int i)
{
MyCriticalSection myCriticalSectionB; // LockB

m_Int = i;
}
protected:
int m_Int;
};

我认为以上设计是正确的,如果您发现错误请指正。LockA 的用法有两个功能: 1> 它防止函数 GetNum 被多个线程同时调用。 2> 它防止函数 GetNum 和 SetNum 同时访问 m_Int。

这是我的问题:变量 myCriticalSectionA 和 myCriticalSectionB 是类 MyCriticalSection 的两个不同实例。为什么他们可以相互协作,使锁机制如预期的那样工作?

我的猜测是 CRITICAL_SECTION 不知何故有一些静态标志,因此它的不同实例可以相互通信。

如有错误请指正

====更新====

class MyCriticalSection : protected CRITICAL_SECTION
{
public:
MyCriticalSection()
{
InitializeCriticalSection(this);

}
~MyCriticalSection()
{
DeleteCriticalSection(this);
}
void Lock()
{
EnterCriticalSection(this);
}
void UnLock()
{
LeaveCriticalSection(this);
}
};

class MyClass
{
public:
MyClass() : m_Int(0) {}

int GetNum()
{
m_Lock.Lock();
// do something here
m_Lock.UnLock();
return m_Int;
}

int SetNum(int i)
{
m_Lock.Lock();
m_Int = i;
m_Lock.UnLock();
}
protected:
int m_Int;
MyCriticalSection m_Lock;
};

谢谢

最佳答案

你的更新也好不到哪儿去。如果你想以 RAII 风格做到这一点,那么你需要更加努力地工作。关键是您需要将静态分配的临界区对象与所有需要保护的 block 本地的锁分开。

以下摘自Jonathan Dodds但这是一个经典的模式。

class CriticalSection
{
public:
CriticalSection()
{ ::InitializeCriticalSection(&m_rep); }
~CriticalSection()
{ ::DeleteCriticalSection(&m_rep); }

void Enter()
{ ::EnterCriticalSection(&m_rep); }
void Leave()
{ ::LeaveCriticalSection(&m_rep); }

private:
// copy ops are private to prevent copying
CriticalSection(const CriticalSection&);
CriticalSection& operator=(const CriticalSection&);

CRITICAL_SECTION m_rep;
};

虽然您可以通过继承 CRITICAL_SECTION 来做到这一点,但我觉得封装更合适。

接下来定义锁:

class CSLock
{
public:
CSLock(CriticalSection& a_section)
: m_section(a_section) { m_section.Enter(); }
~CSLock()
{ m_section.Leave(); }

private:
// copy ops are private to prevent copying
CSLock(const CSLock&);
CSLock& operator=(const CSLock&);

CriticalSection& m_section;
};

最后是一个使用示例:

class Example
{
public:
bool Process( … );



private:
CriticalSection m_criticalsection;


};

bool Example::Process( … )
{
CSLock lock(m_critsection);

// do some stuff

}

重点是关键部分只有一个实例,所有线程共享。这就是关键部分起作用的原因。

在对比中,可能有许多 CSLock 实例,它们都在同一临界区中同时存在。这允许多个线程调用 Process() 方法,但其代码在 CSLock 实例的生命周期内被序列化,该实例在单个共享临界区上。

关于c++ - 关于CRITICAL_SECTION的使用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5421387/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com