peakzhang 发表于 2008-9-21 15:10:19

windows关键段可以静态初始化吗

windows关键段可以静态初始化吗,我想在一个类似单体的    类的静态成员函数   中同步类的共享数据,类的构造函数都是私有的,不能在其中InitializeCriticalSection。由于静态成员函数不能访问非静态数据成员,出现了下面问题:什么时候调用InitializeCriticalSection?
staticvoid * getInstance()
{
EnterCriticalSection(&CriticalSection); //问题是CriticalSection必须先InitializeCriticalSection才能加锁
//这里可以安全访问。
LeaveCriticalSection(&CriticalSection);
}

peakzhang 发表于 2008-9-21 15:10:25

没问题。不过貌似你的模式有些问题,说说为什么这样操作?
InitializeCriticalSection可以另外启用函数进行调用。

peakzhang 发表于 2008-9-21 15:10:32

这样做是为了移植一个linux下面的 程序,linux下面 可以

头文件中:static pthread_mutex_t            m_ConfigsMutex;

cpp文件中:

pthread_mutex_t CConfig::m_ConfigsMutex = PTHREAD_MUTEX_INITIALIZER;

这样在static CConfig* getInstance(const string& configfile);中可以直接加锁。非常方便。

“InitializeCriticalSection可以另外启用函数进行调用。” 是谁起函数呢?getInstance吗?那不还是间接调用了非静态成员?如getInstance中另起函数fun,那么要求fun也是静态的,在fun中还是不能调用InitializeCriticalSection。还是不明白,^_^。不知道是我哪里理解有出入。

peakzhang 发表于 2008-9-21 15:10:39

你可以这样做,定义一个简单的类型,如:MyCriticalSection,继承自CRITICAL_SECTION,然后在构造中进行初始化

class MyCriticalSection : public CRITICAL_SECTION
{
public:
MyCriticalSection(void)
{
::InitializeCriticalSection(this);
}

~MyCriticalSection(void)
{
::DeleteCriticalSection(this);
}
};

然后,定义一个全局的MyCriticalSection对象。

或者,在你的函数中这样使用:
staticvoid * getInstance()
{
static MyCriticalSection cs;

EnterCriticalSection(&cs);

LeaveCriticalSection(&cs);

}

peakzhang 发表于 2008-9-21 15:10:47

其实你所需要的就是有一个能够定义一个CRITICAL_SECTION对象,并同时调用InitializeCriticalSection()函数来初始化该对象的方式

如果你使用的是MFC,那你可以使用MFC提供的CCriticalSection来完成这样的功能,当然你也可以自己实现一个类型MFC的功能

class MyAnotherCriticalSection
{
public:
MyAnotherCriticalSection(void)
{
::InitializeCriticalSection(&m_sect);
}

~MyAnotherCriticalSection(void)
{
::DeleteCriticalSection(&m_sect);
}

operator CRITICAL_SECTION*()
{
return (&m_sect);
}

private:
CRITICAL_SECTION m_sect;
}

你可以在任何使用CRITICAL_SECTION的地方来同样的使用MyAnotherCriticalSection而不用担心初始化和删除

如果你使用的是ACE,那你大可不必使用这样的方式,ACE已经封装了多个同步操作对象,你可以使用ACE的这些对象来完成你需要的功能,如:
ACE_Mutex
页: [1]
查看完整版本: windows关键段可以静态初始化吗