- °³¿ä
- C++/½Ì±Û ½º·¹µå ¹öÀü
- C++/´ÙÁß ½º·¹µå ¹öÀü
- ¸µÅ©
1 °³¿ä
- °´Ã¼°¡ ÇÁ·Î±×·¥ ³»¿¡ ´Ü Çϳª¸¸ Á¸ÀçÇÏ´Â °ÍÀ» º¸ÀåÇϱâ À§ÇÑ ÆÐÅÏ
- °¡Àå ³Î¸® »ç¿ëµÇ´Â ÆÐÅÏ?
- °á±¹Àº Àü¿ªº¯¼ö¿Í ´Ù¸¦ °ÍÀÌ ¾øÀ¸¹Ç·Î, ½Ì±ÛÅæÀÇ °ú¿ëÀº À߸øµÈ ÇÁ·Î±×·¥ µðÀÚÀÎÀÇ Â¡ÈĶó°í º¼ ¼ö ÀÖ´Ù.
2 C++/½Ì±Û ½º·¹µå ¹öÀü
...»ý·«...
//////////////////////////////////////////////////////////////////////////////
/// \class Singleton
/// \brief ½Ì±Û ½º·¹µå¿ë ½Ì±ÛÅæ ÆÐÅÏ ÅÛÇø´ Ŭ·¡½º.
///
/// ¾î¶² Ŭ·¡½ºÀÇ ÀνºÅϽº°¡ Çϳª»ÓÀÎ °ÍÀ» º¸ÀåÇϰí, ±× ¿ÀºêÁ§Æ®¿¡ ´ëÇÑ
/// Àü¿ªÀûÀÎ Á¢±ÙÀ» °¡´ÉÇÏ°Ô Çϱâ À§ÇÑ Singleton ÆÐÅÏÀ» Ŭ·¡½º·Î ¸¸µé¾î³õ¾Ò´Ù.
/// ¾î¶² °´Ã¼¸¦ Çϳª¸¸ »ý¼ºÇϰíÀÚ ÇÑ´Ù¸é, ÀÌ Å¬·¡½º¸¦ ¾Æ·¡¿Í °°Àº ¹æ½ÄÀ¸·Î
/// »ó¼Ó¹Þ±â ¹Ù¶õ´Ù.
///
/// <pre>
/// class TheOne : public Singleton<TheOne>
/// {
/// friend class Singleton; // friend ¼±¾ðÀÌ ÇÊ¿äÇÏ´Ù.
/// private: // »ý¼ºÀÚ ¹× ¼Ò¸êÀÚ´Â privateÀ¸·Î ¼±¾ðÇØ¾ßÇÑ´Ù.
/// TheOne();
/// ~TheOne();
/// };
/// </pre>
//////////////////////////////////////////////////////////////////////////////
template <typename T>
class __declspec(noinline) Singleton
{
protected:
Singleton() {}
virtual ~Singleton() {}
public:
static T* instance()
{
static T s_instance;
return &s_instance;
}
private:
Singleton(const Singleton&) {}
const Singleton& operator = (const Singleton&) { return *this; }
};
...»ý·«...
3 C++/´ÙÁß ½º·¹µå ¹öÀü
...»ý·«...
//////////////////////////////////////////////////////////////////////////////
/// \class Singleton
/// \brief ½Ì±ÛÅæ ÆÐÅÏ ÅÛÇø´ Ŭ·¡½º.
///
/// ¾î¶² Ŭ·¡½ºÀÇ ÀνºÅϽº°¡ Çϳª»ÓÀÎ °ÍÀ» º¸ÀåÇϰí, ±× ¿ÀºêÁ§Æ®¿¡ ´ëÇÑ
/// Àü¿ªÀûÀÎ Á¢±ÙÀ» °¡´ÉÇÏ°Ô Çϱâ À§ÇÑ Singleton ÆÐÅÏÀ» Ŭ·¡½º·Î ¸¸µé¾î³õ¾Ò´Ù.
/// ¾î¶² °´Ã¼¸¦ Çϳª¸¸ »ý¼ºÇϰíÀÚ ÇÑ´Ù¸é, ÀÌ Å¬·¡½º¸¦ ¾Æ·¡¿Í °°Àº ¹æ½ÄÀ¸·Î
/// »ó¼Ó¹Þ±â ¹Ù¶õ´Ù.
///
/// <pre>
/// class TheOne : public Singleton<TheOne>
/// {
/// friend class Singleton; // friend ¼±¾ðÀÌ ÇÊ¿äÇÏ´Ù.
/// private: // »ý¼ºÀÚ ¹× ¼Ò¸êÀÚ´Â privateÀ¸·Î ¼±¾ðÇØ¾ßÇÑ´Ù.
/// TheOne();
/// ~TheOne();
/// };
/// </pre>
//////////////////////////////////////////////////////////////////////////////
template <typename TYPE>
class Singleton
{
protected:
/// ´Ü ÇϳªÀÇ °´Ã¼ Æ÷ÀÎÅÍ
static TYPE* volatile s_pInstance;
/// ´ÙÁß ½º·¹µå »óȲ¿¡¼ÀÇ ¸Þ¸ð¸® ´©¼ö¸¦ ¹æÁöÇϱâ À§ÇÑ ¶ô
static BasicCriticalSection s_InstanceSection;
protected:
/// \brief ±âº» »ý¼ºÀÚ´Â ¿ÜºÎ »ý¼ºÀ» ¸·±â À§ÇØ protected·Î ¼±¾ðÇÑ´Ù.
Singleton() { atexit(clear); }
/// \brief ¼Ò¸êÀÚµµ ¸¶Âù°¡Áö.
virtual ~Singleton() {}
public:
/// \brief Çϳª»ÓÀÎ °´Ã¼ÀÇ Æ÷ÀÎÅ͸¦ ¹ÝȯÇÑ´Ù.
/// \return TYPE* Çϳª»ÓÀÎ °´Ã¼ÀÇ Æ÷ÀÎÅÍ
static TYPE* instance(void)
{
// ÀÌ ºÎºÐ¿¡¼ ¶ôÀ» ¾²Áö ¾Ê°Ô µÇ¸é, ¸ÖƼ ½º·¹µå ȯ°æ¿¡¼ µÎ ½º·¹µå°¡
// µ¿½Ã¿¡ Á¢±ÙÇÏ°Ô µÇ¸é °´Ã¼¸¦ µÎ °³ »ý¼ºÇÏ°Ô µÇ¸ç ÀÌ Áß Çϳª´Â
// ¹ö·ÁÁö°Ô µÈ´Ù.
// ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇØ Double-checked lockÀ̶ó°í ºÎ¸£´Â ÆÐÅÏÀ»
// ½è´Âµ¥, ÀÌ´Â ¸Å¹ø ¶ôÀ» üũÇÏ´Â ºÎ´ãÀ» ÁÙÀ̸é¼, ¾ÈÀüÇÏ°Ô °´Ã¼¸¦
// »ý¼ºÇÒ ¼ö ÀÖ´Â ÆÐÅÏÀÌ´Ù.
// Áï s_pInstance == 0À» µÎ ¹ø ½ÇÇàÇÔÀ¸·Î¼ ¾ÈÀüÇÑ °´Ã¼ÀÇ »ý¼ºÀÌ
// º¸ÀåµÇ´Â °ÍÀÌ´Ù.
//
// *** CAUTION ***
// ¾Æ·¡ÀÇ ÄÚµå´Â Æ÷ÀÎÅÍ ´ëÀÔ ¿¬»êÀÌ Atomic OperationÀ̶ó´Â °ÍÀ»
// °¡Á¤ÇÏ°í ¸¸µç ÄÚµå´Ù. ¿¹¸¦ µé¾î 16ºñÆ® À©µµ¿ì¿¡¼ 32ºñÆ® Æ÷ÀÎÅ͸¦
// ´Ù·ç´Â °ÍÀº µÎ »çÀÌŬ¿¡ °ÉÃļ ÀϾ±â ¶§¹®¿¡ ÀÌ´Â Atomic
// OperationÀÌ ¾Æ´Ï´Ù. ÀÌ·± °æ¿ì ¾Æ·¡ÀÇ ÄÚµå´Â ¹®Á¦¸¦ ÀÏÀ¸Å³ ¼ö°¡
// ÀÖ´Ù. ÀÌ·± °æ¿ì¸¦ ÇÇÇØ°¡±â À§Çؼ´Â CPU º¥´õ¸¶´Ù ´Ù¸¥
// ¸Þ¸ð¸® ¹è¸®¾î ¿¬»êÀ» Æ÷ÀÎÅÍ ¿¬»ê À§ ¾Æ·¡·Î Áý¾î³Ö¾î¾ß ÇÑ´Ù.
if (s_pInstance == 0)
{
s_InstanceSection.enter();
if (s_pInstance == 0)
{
s_pInstance = new TYPE;
}
s_InstanceSection.leave();
}
return s_pInstance;
}
/// \brief Çϳª»ÓÀÎ °´Ã¼¸¦ »èÁ¦ÇÑ´Ù.
static void clear(void)
{
// ¸¶Âù°¡Áö·Î Double-checked lockÀ» »ç¿ëÇß´Ù.
if (s_pInstance != 0)
{
s_InstanceSection.enter();
if (s_pInstance != 0)
{
delete s_pInstance;
s_pInstance = 0;
}
s_InstanceSection.leave();
}
}
private:
/// \brief º¹»ç »ý¼ºÀÚ´Â ¿ÜºÎ »ý¼ºÀ» ¸·±â À§ÇØ privateÀ¸·Î ¼±¾ðÇÑ´Ù.
Singleton(const Singleton<TYPE>&) {}
/// \brief ´ëÀÔ ¿¬»êÀÚ´Â ¿ÜºÎ »ý¼ºÀ» ¸·±â À§ÇØ privateÀ¸·Î ¼±¾ðÇÑ´Ù.
const Singleton<TYPE>& operator = (const Singleton<TYPE>&) { return *this; }
};
template <typename TYPE>
TYPE* volatile Singleton<TYPE>::s_pInstance = 0;
template <typename TYPE>
BasicCriticalSection Singleton<TYPE>::s_InstanceSection;
...»ý·«...
class BasicCriticalSection
{
private:
CRITICAL_SECTION m_Win32CS;
public:
BasicCriticalSection() { ::InitializeCriticalSection(&m_Win32CS); }
virtual ~BasicCriticalSection() { ::DeleteCriticalSection(&m_Win32CS); }
void enter() { ::EnterCriticalSection(&m_Win32CS); }
void leave() { ::LeaveCriticalSection(&m_Win32CS); }
private:
BasicCriticalSection(const BasicCriticalSection&) {}
const BasicCriticalSection& operator = (const BasicCriticalSection&) { return *this; }
};
...»ý·«... º¸´Ù½ÃÇÇ ÀνºÅϽº ÀÚ½ÅÀÇ »èÁ¦¸¦ À§ÇØ atexit ÇÔ¼ö¸¦ ÀÌ¿ëÇϴµ¥, atexit ÇÔ¼ö¸¦ ÅëÇØ µî·ÏµÈ ÇÔ¼öµéÀº main ÇÔ¼ö°¡ ¹ÝȯµÈ ´ÙÀ½ ½ÇÇàµÈ´Ù. ±×·¡¼ ¸Þ¸ð¸® ´©¼ö¸¦ Àâ¾ÆÁÖ´Â ÇÁ·Î±×·¥µé¿¡¼ ÀνºÅϽº¿¡¼ »ç¿ë ÁßÀÎ ¸Þ¸ð¸®¸¦ ´©¼öµÈ °ÍÀ̶ó°í ÆÇ´ÜÇÏ´Â °æ¿ì°¡ ¸¹´Ù. (»ç½Ç ¸Þ¸ð¸® ´©¼ö°¡ ¸Â´Ù. main ÇÔ¼ö°¡ ¸®ÅϵǾú´Âµ¥µµ Á¤¸®µÇÁö ¾ÊÀº ¸Þ¸ð¸®´Ï±î.)
ÀÌ ¹®Á¦¸¦ ÇØ°áÇϱâ À§Çؼ´Â main ÇÔ¼ö°¡ ¹ÝȯµÇ±â Àü¿¡ atexit ÇÔ¼öµéÀ» ¸í½ÃÀûÀ¸·Î ½ÇÇàÇØÁà¾ß ÇÑ´Ù. VisualCpp 2005 ±âÁØÀ¸·Î´Â ÀÌ ¿ªÇÒÀ» ÇÏ´Â ÇÔ¼ö°¡ _cexit ÇÔ¼ö´Ù. atexit ÇÔ¼ö°¡ Ç¥ÁØ ÇÔ¼ö´Ï, ´Ù¸¥ ÄÄÆÄÀÏ·¯¿¡µµ _cexit ÇÔ¼ö¿Í °°Àº ¿ªÇÒÀ» ÇÏ´Â ÇÔ¼ö°¡ ÀÖÀ¸¸®¶ó.
´Ù¸¸ Ŭ·¡½º ŸÀÔÀÇ Àü¿ª º¯¼ö°¡ ÀÖ´Â °æ¿ì, ¼Ò¸êÀÚ°¡ µÎ¹ø È£ÃâµÉ ¼ö ÀÖ´Ù. VisualCpp ÄÄÆÄÀÏ·¯´Â ÀÌ·± Àü¿ª Ŭ·¡½º º¯¼ö ¼Ò¸êÀÚµéÀ» atexit ÇÔ¼ö¸¦ ÅëÇØ ½ÇÇàÇϱ⠶§¹®ÀÌ´Ù. atexit Çڵ鷯 ¸®½ºÆ®¸¦ ºñ¿ö¹ö¸®´Â ÇÔ¼ö°¡ ÀÖÀ» ¹ýµµ Çѵ¥, ¸ø ã°Ú´Ù. ¾î¿ ¼ö ¾øÀÌ atexit ºñ½ÁÇÑ ¿ªÇÒÀ» ÇØÁÖ´Â ÇÔ¼ö¸¦ ¸¸µé¾î¾ß ÇÑ´Ù.
// Á¾·á ÇÔ¼ö ŸÀÔ Á¤ÀÇ
typedef void (__cdecl *EXIT_FUNCTION)(void);
// Á¾·á ÇÔ¼ö Ä÷º¼Ç
std::vector<EXIT_FUNCTION> g_ExitFunctions;
// Á¾·á ÇÔ¼ö Ãß°¡¸¦ À§ÇÑ ¶ô (¾Æ¹« ¶ôÀ̳ª »ç¿ë)
cLock g_ExitFunctionLock;
// cSingleton »ý¼ºÀÚ¿¡¼ atexit ´ë½Å¿¡ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇØÁØ´Ù.
void AddExitFunction(EXIT_FUNCTION func)
{
g_ExitFunctionLock.Lock();
g_ExitFunctions.push_back(func);
g_ExitFunctionLock.Unlock();
}
// ±×¸®°í ¸ÞÀÎ ÇÁ·Î±×·¥ÀÌ ³¡³¯ ¶§Âë ¾Æ·¡¿Í °°Àº Äڵ带 È£ÃâÇÑ´Ù.
...
g_ExitFunctionLock.Lock();
for (size_t i=0; i<g_ExitFunctions.size(); ++i)
(g_ExitFunctions[i])();
g_ExitFunctionLock.Unlock();
...
4 ¸µÅ©
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)