关键部分,如果是多线程应用程序中的其他条件
critical section and if ,else condition in multithreaded app
如果我以下所示,我可以将关键部分放在许多条件下吗?
示例1
somefunction()
{
EnterCriticalSection(&(g_variable));
if (...)
{
if (...)
{
...
}
else
{
...
if (...)
{...}
else if (...)
{...}
LeaveCriticalSection(&(g_variable));
}
}
else
{
...
}
}
或这样筑巢:
示例2
EnterCriticalSection(&g_List);
EnterCriticalSection(&g_Variable);
...
LeaveCriticalSection(&g_List);
LeaveCriticalSection(&g_Variable);
事先感谢您的帮助。
您 can 做的事情与您应该做的事情有所区别。
您 can 做您在问题中显示的事情。至少在我看来,您的应该做的事情(因为您使用的是C )是使用RAII包装器来自动获取您的LeaveCricitalSection呼叫以匹配您的肠cricationalliticalsection呼叫。
class crit_sect {
CRITICAL_SECTION cs;
void lock() { EnterCriticalSection(&cs); }
void unlock() { LeaveCriticalSection(&cs); }
friend class lock;
crit_sect(crit_sect const &); /* = delete; */
crit_sect &operator=(crit_sect const &other); /* = delete; */
public:
crit_sect() { InitializeCriticalSection(&cs); }
~crit_sect() { DeleteCriticalSection(&cs); }
};
class lock {
crit_sect &cs;
public:
lock(crit_sect &c) : cs(c) { cs.lock(); }
~lock() { cs.unlock(); }
};
使用这些,您将有类似的东西:
if (whatever) {
lock list_lock(g_List);
lock var_lock(g_Variable);
// ...
}
...并且当执行留下定义两个锁的范围时,将执行驱动器,自动解锁关键部分。这很方便;如果您使用异常,它变得更加重要,因为这意味着如果您通过异常而不是通过正常执行退出范围,那么关键部分仍将被解锁。
简短答案:是的,您可以。但是很容易用成对的Enter/LeaveCricection犯错误。您自己的代码表明,在顶部将关键部分放在顶部之后,在某些代码路径中未释放临界部分的代码路径。其中一条路径是第一个if statement的其他块的地方,而另一个更阴险的路径是当两者之间的某些代码引发异常时。
您将问题标记为C ;如果可用C 11,则有一个绝佳的选择:标准标头的类,例如Recursive_mutex和Lock_Guard。您的代码看起来像这样:
recursive_mutex g_variable;
someFunction()
{
lock_guard<recursive_mutex> lock(g_variable);
if (...)
...
else
...
}
现在,您可以保证二线释放()。而且您必须少输入,并且您的代码也是可移植的。
在示例1中,这是坏习惯。更好的威胁临界部分作为代码块
EnterCriticalSection(&g_Variable);
{
....
}
LeaveCriticalSection(&g_Variable);
更好的是使用范围CS类:
class CScopeCS{
CRITICAL_SECTION& m_cs;
public:
CScopeCS(CRITICAL_SECTION& cs):m_cs(cs){
EnterCriticalSection(cs);
}
~CScopeCS(){
LeaveCriticalSection(m_cs);
}
}
,当从临界部分块退出时,它将自动调用灾难。
{
CScopeCS scopeLock(g_cs);
....
}//end of critical section
在示例2中,它会像您写的那样工作,但是最好先离开最后一个:
EnterCriticalSection(&g_List);
EnterCriticalSection(&g_Variable);
...
LeaveCriticalSection(&g_Variable);
LeaveCriticalSection(&g_List);
但是,您必须在代码中以相同的顺序进行两个关键部分,以防止死锁。(即首先是g_list,然后g_variable)如果您已经输入了g_variable并要输入g_list,则必须离开g_variable并按顺序进行操作。
- 在Visual Studio中单实例Qt应用程序版本5.11.1中,在所有其他窗口的顶部打开Qt MainWindow
- C++ - 从 MFC 应用程序启动记事本,并将其默认标题从 "Untitled - Notepad" 更改为其他内容
- 从 Windows 中的其他应用程序 GUI 中提取数据
- 打开应用程序主窗口 在系统托盘图标中的其他应用程序之上
- 如何在没有作弊引擎的情况下从其他应用程序获取指针地址?
- Xlib XSENDEVENT在其他应用程序/过程中
- CreateProcess:某些应用程序运行其他应用程序
- 我的COCOS2D游戏开始,而不是其他音乐应用程序停止
- Create_task():称为“接口”的应用程序,该接口已编辑为其他线程进行编组
- 全球安装的键盘钩可防止键盘输入其他应用程序
- 如何将OpenCV的输出显示或流式传输到HTML页面或其他一些客户端应用程序
- 创建 COM 接口指针在开发计算机上有效,但会导致其他计算机上的应用程序崩溃
- Cython 带 STL 矢量和没有 NumPy 可以从其他应用程序调用,缺少什么?
- 其他静态阵列破坏了OMAPL138目标(CCS5.2)上的DSP应用程序
- 我可以在OpenFrameWorks中调用应用程序以外的其他内容
- 如何在 Linux 应用程序中专门使用其他键盘
- 与其他应用程序的交互
- 关键部分,如果是多线程应用程序中的其他条件
- 默认的Qt控制台应用程序不会"Hello World"...或做任何其他事情
- 是否有预处理器宏可以让我知道应用程序是控制台类型还是其他类型