- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
给定以下代码,
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/
我正在使用 CRITICAL_SECTION 对象。如果我在程序关闭时不调用 DeleteCriticalSection(),操作系统会自动回收泄漏的资源吗?还是永久泄露? 谢谢,戴夫 最佳答案 是
我可以初始化和使用的关键部分的数量是否有限制? 我的应用程序创建了许多(几千个)需要线程安全的对象。如果我在每个部分中都有一个关键部分,那会占用太多资源吗? 我认为因为我需要声明我自己的 CRITIC
我的理解是WaitForMultipleObjects和 CRITICAL_SECTION旨在等待线程完成。并且它们都被描述为线程之间的进程和线程同步机制。如果它们旨在实现相同的目标,它们可以互换使用
Win32 CRITICAL_SECTION 包含哪些数据,有多大? 这是没有记录的,可能是特定于实现的,但我很想知道 最佳答案 这是我安装的 Windows Vista SDK: WinNT.h:
目前我的应用程序中有一个 boost::mutex 代码部分,看起来像这样 {//Lock boost::unique_lock lock(some_mutex); while(containe
我的库中有这些类。 class SingleLock { public: SingleLock(CRITICAL_SECTION *pCS); ~SingleLock(); priva
我有一个使用 CRITICAL_SECTION 的简单 C 程序。由于某种原因,它似乎一次又一次地进入CRITICAL_SECTION并没有真正执行里面的代码,导致线程死锁。我似乎找不到原因。 代码如
我有一个维护列表的对象;其中一个辅助方法需要 锁定列表 找到第一个元素 解锁列表 通知另一个线程开始清理操作 等待另一个线程完成 重复此操作直到列表为空。 清理操作从另一个线程的列表中删除对象,因此它
可以使用 CRITICAL_SECTION 变量来实现互斥。 我的问题是:CRITICAL_SECTION 是否支持复制?如果我按值将一个传递给另一个线程,我能确定互斥会起作用吗? 如果答案是“你不能
因此,当我使用“EnterCriticalSection”和“LeaveCriticalSection”时,我抛出了一个异常,这是我当前的设置: void printer::Unlock() {
我目前正在开发一款分为两部分的游戏:引擎位于 .dll 中,实际游戏代码位于 .exe 中。该引擎与其他头文件一起包含一个管理所有组件的引擎,范围从 Win32 特定对象和指针到 D3D11。这些组件
我正在处理一个共享项目。我遇到了一些标识符错误,VS C++ 2005 不知道 CRITICAL_SECTION 和 LPCRITICAL_SECTION。 LPCRITICAL_SECTION Ge
现在写复杂的class,感觉用了很多CRITICAL_SECTION。 据我所知,某些类型有原子操作,它们总是在没有任何硬件或软件中断的情况下执行。 我想检查一下我是否理解正确。 要设置或获取原子值,
我有一个这样声明的接口(interface): #if defined _WIN32 || _WIN64 typedef CRITICAL_SECTION MutexHandl
在我的 const' 中 - 我希望 'secondCommand' 仅在 'firstCommand' 之后被调用。我尝试使用 EnterCriticalSection,但问题是,从哪里启动我的锁
似乎 CRITICAL_SECTION 性能在 Windows 8 及更高版本上变差了。 (见下图) 测试非常简单:一些并发线程每个执行 300 万次锁以独占访问一个变量。您可以在问题的底部找到 C+
是否有针对 C++ 的 Win32 CRITICAL_SECTION 的轻量级跨平台替代方案?我试图让我的 Windows 应用程序平台不可知,但 std::recursive_mutex 比 CRI
我正在使用 boost_logging为我的项目。 在我的一个文件中,我只使用了我的日志记录工具: LDBG_ c:\boost\boost_logging\boost\logging\detail\
我无法构建以下代码 (vs2013) block 并收到错误 “error C2248: 'Concurrency::critical_section::critical_section' : can
std::mutex 是用关键部分实现的,这就是为什么它比 OS Mutex(在 Windows 上)快得多。但是它不如 Windows CRITICAL_SECTION 快。 计时只是一个线程中的一
我是一名优秀的程序员,十分优秀!