我需要一个简单的“一次一个”锁在一段代码上。考虑一下可以从多个线程运行的函数func
:
void func()
{
// locking/mutex statement goes here
operation1();
operation2();
// corresponding unlock goes here
operation3();
}
我需要确保operation1
和operation2
总是“一起”运行。对于C#,我会在这两个调用之间使用一个简单的lock
块。什么是C++/Win32/MFC的等价物?
可能是某种Mutex
发布于 2009-03-11 16:26:09
临界区将会工作(它们是轻量级的互斥)。InitializeCriticalSection、EnterCriticalSection、LeaveCriticalSection和DeleteCriticalSection是要在MSDN上查找的函数。
void func()
{
// cs previously initialized via InitializeCriticalSection
EnterCriticalSection(&cs);
operation1();
operation2();
LeaveCriticalSection(&cs);
operation3();}
}
编辑:临界区比互斥锁更快,因为临界区主要是用户模式原语-在非争用获取(通常是常见情况)的情况下,没有系统调用内核,而获取需要数十个周期的顺序。内核交换机的开销更大(大约需要数百个周期)。调用内核的唯一时间临界区是为了阻塞,这涉及到等待内核原语(互斥或事件)。获取互斥总是涉及到对内核的调用,因此速度要慢上几个数量级。但是,临界区只能用于同步一个进程中的资源。为了跨多个进程进行同步,需要一个互斥锁。
发布于 2009-03-11 17:56:06
修复上面的Michael solution。
Michael solution非常适合于C应用程序。但在C++中使用时,由于可能出现异常,因此不鼓励使用这种样式。如果在operation1或operation2中发生异常,则临界区将不会正确保留,所有其他线程将阻塞等待。
// Perfect solutiuon for C applications
void func()
{
// cs previously initialized via InitializeCriticalSection
EnterCriticalSection(&cs);
operation1();
operation2();
LeaveCriticalSection(&cs);
operation3();}
}
// A better solution for C++
class Locker
{
public:
Locker(CSType& cs): m_cs(cs)
{
EnterCriticalSection(&m_cs);
}
~Locker()
{
LeaveCriticalSection(&m_cs);
}
private:
CSType& m_cs;
}
void func()
{
// cs previously initialized via InitializeCriticalSection
{
Locker lock(cs);
operation1();
operation2();
}
operation3();
}
发布于 2009-03-11 16:31:15
最好的方法是使用临界区,使用EnterCriticalSection和LeaveCriticalSection。唯一棘手的部分是,您需要首先用InitializeCriticalSection初始化一个临界区。如果此代码位于类中,则将初始化放入构造函数中,并将CRITICAL_SECTION数据结构作为该类的成员。如果代码不是类的一部分,您可能需要使用全局或类似的方法来确保它被初始化一次。
https://stackoverflow.com/questions/635276
复制相似问题