ã¹ããªãŒã ã¯åŸ æ©ããå¿ èŠããããŸãã ãªãœãŒã¹ã«æä»çã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸã§ããŸãã¯å®è¡ããã¿ã¹ã¯ã衚瀺ããããŸã§åŸ ã¡ãŸãã ã¹ã¬ãããOSã«ãŒãã«ã¹ã±ãžã¥ãŒã©ã«ãã£ãŠå®è¡ãããªãåŸ æ©ã¡ã«ããºã ã®1ã€ã¯ã ã»ããã©ã䜿çšããŠå®è£ ãããŸãã
ã»ããã©ã¯å€ããªã£ãŠãããšæã£ãŠããŸããã 1960幎代ããã«ãã¹ã¬ããããã°ã©ã ããã®ä»ã®ããã°ã©ã ãæžãã人ã¯ã»ãšãã©ããªãã£ããããEdsger Dijkstraã¯æ°ããåæã¡ã«ããºã -ã»ããã©ã®ã¢ã€ãã¢ãææ¡ããŸããã ã»ããã©ã®å©ããåããŠãå©çšå¯èœãªãªãœãŒã¹ã®æ°ã远跡ãããããã¥ãŒããã¯ã¹ã®ããã¡ãªãé¡äŒŒç©ãäœæãããã§ããããšã¯ç¥ã£ãŠããŸããããããã¯ãç§ãèããããã«ãç¯å²ãéãããŠããŸãã
ã»ããã©ãšã¢ãããã¯æäœã®ã¿ã䜿çšããŠãä»ã®ãã¹ãŠã®åæããªããã£ããäœæã§ããããšã«æ°ä»ãããšããç§ã®æèŠã¯å€ãããŸããã
- 軜éãã¥ãŒããã¯ã¹
- 軜éã®æ¡ä»¶å€æ°
- 軜éãªèªã¿åã/æžã蟌ã¿ããã¯
- é£äºå²åŠè ã®åé¡ã解決ããããã®ããªããã£ã
- 軜éã»ããã©
ãããã®ããªããã£ãã¯ãã¹ãŠããŠãŒã¶ãŒç©ºéã§å®å šã«å®è¡ããããšããæå³ã§è»œéã§ããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ããã¹ã¬ããããã¯ãèŠæ±ããåã«ïŒããã¯ãªãã·ã§ã³ã®æ¡ä»¶ã§ãïŒã«ãŒãå ã§å転ã§ããŸãïŒäŸã¯GitHubã§å©çšå¯èœã§ãïŒãç§ã®ããªããã£ãã©ã€ãã©ãªã¯ãWindowsãMacOSãiOSãLinuxãããã³ãã®ä»ã®POSIXäºæOSã®ã·ã¹ãã ã»ããã©ã®ã©ãããŒã§ããSemaphoreã¯ã©ã¹ãå®è£ ããŠããŸãã ãããã®ããªããã£ãããããžã§ã¯ãã«ç°¡åã«è¿œå ã§ããŸãã
ããŠã³ãµãŒã»ããã©
ãã¬ã³ãã£ãªãã€ãã¯ã©ãã®åã®åã®ããã«ãããããã®ã¹ã¬ãããå®è¡ãåŸ ã£ãŠãããšæ³åããŠãã ããã ã»ããã©ã¯ãå ¥ãå£ã®åã«ããèŠåå¡ã§ãã 圌ã¯ãé©åãªæ瀺ãäžããããå Žåã«ã®ã¿ãã¯ã©ãã®äžã«å ¥ãããšãã§ããŸãã
åã¹ã¬ããã¯ããã®ãã¥ãŒã«å ¥ãã¿ã€ãã³ã°ã決å®ããŸãã ãã€ã¯ã¹ãã©ã¯ãã®æäœãPãšåŒã³ãŸããããããã¯ããããããããªãªã©ã³ãèªã®çšèªãžã®åç §ã§ããããçŸä»£ã®ã»ããã©ã®å®è£ ã§ã¯ã åŸ æ©æäœã®ã¿ãèŠã€ããå¯èœæ§ããããŸãã æ¬è³ªçã«ãã¹ã¬ãããwaitã¡ãœãããåŒã³åºããšããã¥ãŒã«ãªããŸãã
ããŠã³ãµãŒãã€ãŸã ã»ããã©ã¯ã1ã€ã®æäœã®ã¿ãå®è¡ã§ããå¿ èŠããããŸãã ãã€ã¯ã¹ãã©ã¯ãã®æäœãVãšåŒã³ãŸããã ãããŸã§ããã®æäœã«ååãä»ããæ¹æ³ã«ã€ããŠã¯åæããããŸããã ååãšããŠã post ã releaseããŸãã¯signalé¢æ°ã«åºãããããšãã§ããŸãã ç§ã¯ä¿¡å·ã奜ãã ãã®ã¡ãœãããåŒã³åºããããšãã»ããã©ã¯åŸ æ©äžã®ã¹ã¬ããã®1ã€ããã¥ãŒããã解æŸãããŸãã ïŒä»ã®åã«åŸ æ©ãåŒã³åºããã¹ã¬ãããšåãã§ããå¿ èŠã¯ãããŸãããïŒ
ãããããã¥ãŒã«ã¹ã¬ããããªããšãã«èª°ããã·ã°ãã«ãåŒã³åºããšã©ããªããŸããïŒ åé¡ãããŸããïŒã¹ã¬ããã®ãããããwaitãåŒã³åºããšãã»ããã©ã¯ãããã¯ããã«ãã®ã¹ã¬ãããããã«ã¹ãããããŸãã ããã«ããã¥ãŒã空ã®ç¶æ ã§ã·ã°ãã«ã 3åé£ç¶ããŠåŒã³åºããããšãã»ããã©ã¯ã åŸ æ©ãåŒãèµ·ããã次ã®3ã€ã®ã¹ã¬ãããåŸ æ©ããã«ãã¥ãŒããã€ãã¹ã§ããããã«ããŸãã
èšããŸã§ããªããã»ããã©ã¯ãã¥ãŒã空ã®ãšãã«ã·ã°ãã«åŒã³åºãã®æ°ãã«ãŠã³ãããå¿ èŠããããŸãã ãããã£ãŠãåã»ããã©ã«ã¯å éšã«ãŠã³ã¿ãè£ åãããŠããããã®å€ã¯ã·ã°ãã«ãåŒã³åºããããšå¢å ãã åŸ æ©ãåŒã³åºããããšæžå°ããŸãã
ãã®ã¢ãããŒãã®å©ç¹ã¯ã åŸ æ©ãšã·ã°ãã«ãåŒã³åºãããé åºã«é¢ä¿ãªããçµæãåžžã«åãã«ãªãããšã§ãïŒã»ããã©ã¯ãå®è¡ã®ããã«åžžã«åãæ°ã®ã¹ã¬ãããã¹ãããããåãæ°ã®åŸ æ©äžã®ã¹ã¬ãããåžžã«ãã¥ãŒã«æ®ããŸãã
1.軜éãã¥ãŒããã¯ã¹
以åã®èšäºã®1ã€ã§ ãç¬èªã®è»œéãã¥ãŒããã¯ã¹ãå®è£ ããæ¹æ³ã«ã€ããŠæ¢ã«èª¬æããŸãã ã åœæãç§ã¯ãããå ±éãã¿ãŒã³ã®é©çšã®äžäŸã«ãããªãããšãç¥ããŸããã§ããããã®äž»ãªã¢ã€ãã¢ã¯ãã¹ã¬ããã®ãããã¯ã«é¢ããææ決å®ãæ°ãããšã³ãã£ãã£ã èè¡ã«å§ããããšã§ãã çŸåšã®ã¹ã¬ããã¯ã€ã³ã©ã€ã³ã§åŸ æ©ããå¿ èŠããããŸããïŒ åœŒã¯åŸ ããã«ã»ããã©ãæž¡ãå¿ èŠããããŸããïŒ ä»ã®ã¹ã¬ãããèµ·åããå¿ èŠããããŸããïŒ
ããã¯ã¹ãªãã£ã¹ã¯ãå éšã»ããã©ã«ãŠã³ã¿ã®çŸåšã®å€ãç¥ããªãã®ãšåæ§ã«ããã¥ãŒã§åŸ æ©ããŠããã¹ã¬ããã®æ°ã«ã€ããŠäœãç¥ããŸããã 代ããã«ã圌ã¯ã©ããããããèªåã®å·ã®æŽå²ãä¿æããªããã°ãªããŸããã 軜éãã¥ãŒããã¯ã¹ã®å®è£ ã«ã€ããŠè©±ããŠããå Žåã¯ãã¢ãããã¯ãªã€ã³ã¯ãªã¡ã³ãããã³ãã¯ãªã¡ã³ãæäœãåããåäžã®ã«ãŠã³ã¿ãŒã§å±¥æŽãä¿åã§ããŸãã ãã®ã«ãŠã³ã¿ãŒãm_contentionãšåŒã³ãŸããã åæã«ãã¥ãŒããã¯ã¹ããã£ããã£ãããã¹ã¬ããæ°ã«é¢ããæ å ±ãä¿åããŸãã
class LightweightMutex { private: std::atomic<int> m_contention; // The "box office" Semaphore m_semaphore; // The "bouncer"
ã¹ã¬ããããã¥ãŒããã¯ã¹ããã£ããã£ããå Žåãããã¯ã¹ãªãã£ã¹ãåŒã³åºããŸããããã«ããã m_contentionå€ãå¢å ããŸãã
public: void lock() { if (m_contention.fetch_add(1, std::memory_order_acquire) > 0) // Visit the box office { m_semaphore.wait(); // Enter the wait queue } }
ã«ãŠã³ã¿å€ããŒãã®å Žåããã¥ãŒããã¯ã¹ã¯ããŒã¯ãããŠããªãç¶æ ã§ãã ãã®å ŽåãçŸåšã®ã¹ã¬ããã¯èªåçã«ãã¥ãŒããã¯ã¹ã®ææè ã«ãªããåŸ æ©ããã«ã»ããã©ããã€ãã¹ãããã¥ãŒããã¯ã¹ã«ãã£ãŠä¿è·ãããã³ãŒãã»ã¯ã·ã§ã³ã§åŒãç¶ãåäœããŸãã
ãã¥ãŒããã¯ã¹ãå¥ã®ã¹ã¬ããã«ãã£ãŠæ¢ã«ãã£ããã£ãããŠããå Žåãã«ãŠã³ã¿ãŒå€ã¯ãŒããã倧ãããªããçŸåšã®ã¹ã¬ããã¯ãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã«å ¥ããŸã§é çªãåŸ ã€å¿ èŠããããŸãã
ã¹ã¬ããããã¥ãŒããã¯ã¹ã解æŸãããšãããã¯ã¹ãªãã£ã¹ã¯å éšã«ãŠã³ã¿ã®å€ã1ã€æžãããŸãã
void unlock() { if (m_contention.fetch_sub(1, std::memory_order_release) > 1) // Visit the box office { m_semaphore.signal(); // Release a waiting thread from the queue } }
ãã¯ãªã¡ã³ãåã®ã«ãŠã³ã¿å€ã1æªæºã®å Žåããã¥ãŒã«ã¯åŸ æ©äžã®ã¹ã¬ããã¯ãªãã m_contentionå€ã¯0ã«çãããŸãŸã§ãã
ã«ãŠã³ã¿ãŒå€ã1ãã倧ããå Žåãå¥ã®ã¹ã¬ãããŸãã¯è€æ°ã®ã¹ã¬ããããã¥ãŒããã¯ã¹ããã£ããã£ããããšãããããã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã«å ¥ãé çªãåŸ ã£ãŠããŸãã ãã®å Žåãã»ããã©ãã¹ã¬ããã®1ã€ãèµ·åãããã¥ãŒããã¯ã¹ããã£ããã£ã§ããããã«ã signalãåŒã³åºããŸãã
ãã±ãã売ãå Žãžã®ååŒã³åºãã¯ã¢ãããã¯æäœã§ãã ãããã£ãŠãè€æ°ã®ã¹ã¬ãããããã¯ãšããã¯è§£é€ã䞊è¡ããŠåŒã³åºããŠãããããã¯åžžã«é£ç¶ããŠèè¡ã«ã¢ã¯ã»ã¹ããŸãã ããã«ããã¥ãŒããã¯ã¹ã®åäœã¯ãèè¡åå ¥ã®å éšç¶æ ã«ãã£ãŠå®å šã«æ±ºå®ãããŸãã èè¡ã«ã¢ã¯ã»ã¹ããåŸãã¹ã¬ããã¯ä»»æã®é åºã§ã»ããã©ã¡ãœãããåŒã³åºãããšãã§ããããã¯å®è¡ã®äžè²«æ§ã«æ±ºããŠéåããŸããã ïŒææªã®å Žåãã¹ã¬ããã¯ã»ããã©ãã¥ãŒã®å Žæã奪ãåããŸããïŒ
ãã®ããªããã£ãã¯ãã¹ã¬ãããã»ããã©ã«é Œããã«ãã¥ãŒããã¯ã¹ããã£ããã£ã§ãããããã軜éããšåŒã°ããŸãã ã·ã¹ãã ã³ãŒã«ãè¡ããã«ã NonRecursiveBenaphoreãšåŒã°ããGitHubã®ãã¥ãŒããã¯ã¹ã³ãŒããå ¬éããŸãããåãå Žæã«è»œéã®ãã¥ãŒããã¯ã¹ã®ååž°ããŒãžã§ã³ããããŸãã ãã ãããããã®ããªããã£ããå®éã«äœ¿çšããããã®åææ¡ä»¶ã¯ãããŸããã ãšã«ãããæãããç¥ãããŠãããã¥ãŒããã¯ã¹ã®å®è£ ã¯è»œéã§ã ã ãã ãããã®ã³ãŒãã¯ããã®èšäºã§èª¬æããä»ã®ãã¹ãŠã®ããªããã£ãã«äœ¿çšãããã¢ãããŒãã®å¿ èŠãªå³ãšããŠæ©èœããŸãã
2.軜éã®æ¡ä»¶å€æ°
ã泚æ transl .:ãªãªãžãã«ã§ã¯ãèè ã¯ãã®ããªããã£ããèªåãªã»ããã€ãã³ããªããžã§ã¯ããšåä»ããŸãããããã®ãããªã¯ãšãªã®æ€çŽ¢ãšã³ãžã³ã¯CïŒã¯ã©ã¹AutoResetEventãžã®ãªã³ã¯ãæäŸãããã®åäœã¯ããã€ãã®ä»®å®ã§std :: condition_variableãšæ¯èŒã§ããŸãã
CppCon 2014ã§ãã²ãŒã ãšã³ãžã³ã®äœææã«æ¡ä»¶å€æ°ãåºã䜿çšãããŠããããšã確èªããŸãããã»ãšãã©ã®å Žåãããã¹ã¬ããã«å¥ã®ã¹ã¬ããïŒããããã¹ã¿ã³ãã€ã¢ãŒãïŒãéç¥ãããã®ããã®äœæ¥ãããããšãéç¥ããŸãïŒ æ³šïŒãã®ãããªäœæ¥ãšããŠã°ã©ãã£ãã¯ãªãœãŒã¹ãå±éããŠGLã³ã³ããã¹ãã«ããŒãããã¿ã¹ã¯ ïŒã
ã€ãŸãã ã·ã°ãã«ã¡ãœãããäœååŒã³åºãããŠããæ¡ä»¶å€æ°ã®å éšã«ãŠã³ã¿ãŒã1ãã倧ãããªããªãããã«ããå¿ èŠããããŸããå®éã«ã¯ã ã·ã°ãã«ã¡ãœãããåŒã³åºããã³ã«ãã¿ã¹ã¯ãå®è¡ãã¥ãŒã«å ¥ããããšãã§ããŸãã ãã®ã¢ãããŒãã¯ã ãã¥ãŒä»¥å€ã®ããŒã¿æ§é ã䜿çšããŠã¿ã¹ã¯ãå®è¡ã«å²ãåœãŠãå Žåã§ãæ©èœããŸã ã
äžéšã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ãæ¡ä»¶å€æ°ãŸãã¯ãã®é¡äŒŒç©ãæŽçããããã®ã·ã¹ãã ããŒã«ãæäŸããŸãã ãã ããäžåºŠã«æ°åã®ã¿ã¹ã¯ããã¥ãŒã«è¿œå ãããšã signalã¡ãœããã®åŒã³åºããã¢ããªã±ãŒã·ã§ã³å šäœã®ããã©ãŒãã³ã¹ã«å€§ãã圱é¿ããå¯èœæ§ããããŸãã
幞ããªããšã«ãèè¡ãã¿ãŒã³ã¯ã ã·ã°ãã«ã¡ãœããã®åŒã³åºãã«é¢é£ãããªãŒããŒããããå€§å¹ ã«åæžã§ããŸãã ããžãã¯ã¯ãã¢ãããã¯æäœã䜿çšããŠããã¯ã¹ãªãã£ã¹ãšã³ãã£ãã£å ã«å®è£ ã§ãããããã¹ã¬ãããé çªãåŸ ã€å¿ èŠãããå Žåã«ã®ã¿ã»ããã©ã«ã¢ã¯ã»ã¹ã§ããŸãã
ãã®ããªããã£ããå®è£ ãã AutoResetEventãšåŒã³ãŸãã ã ä»åãèè¡åå ¥ã¯ããã¥ãŒã§åŸ æ©ããŠããã¹ã¬ããã®æ°ãå¥ã®æ¹æ³ã§äŒèšåŠçããŸãã m_statusãè² ã®å Žåããã®çµ¶å¯Ÿå€ã¯ã»ããã©ã§åŸ æ©ããŠããã¹ã¬ããã®æ°ã瀺ããŸãã
class AutoResetEvent { private: // m_status == 1: Event object is signaled. // m_status == 0: Event object is reset and no threads are waiting. // m_status == -N: Event object is reset and N threads are waiting. std::atomic<int> m_status; Semaphore m_sema;
ã·ã°ãã«ã¡ãœããã§ã¯ã m_statuså€æ°ã®å€ã1ã«éãããŸã§ã¢ãããã¯ã«å¢ãããŸãã
public: void signal() { int oldStatus = m_status.load(std::memory_order_relaxed); for (;;) // Increment m_status atomically via CAS loop. { assert(oldStatus <= 1); int newStatus = oldStatus < 1 ? oldStatus + 1 : 1; if (m_status.compare_exchange_weak(oldStatus, newStatus, std::memory_order_release, std::memory_order_relaxed)) break; // The compare-exchange failed, likely because another thread changed m_status. // oldStatus has been updated. Retry the CAS loop. } if (oldStatus < 0) m_sema.signal(); // Release one waiting thread. }
3.軜éã®èªã¿åã/æžã蟌ã¿ããã¯
åãèè¡ãã¿ãŒã³ã䜿çšããŠãèªã¿åã/æžã蟌ã¿ããã¯ã®ããªããã£ããå®è£ ã§ããŸãã
ãã®ããªããã£ãã¯ãã©ã€ã¿ãŒããªãå Žåã«ã¹ã¬ããããããã¯ããŸããã ããã«ãã©ã€ã¿ãŒãšãªãŒããŒã®äž¡æ¹ã§é£¢vããªããä»ã®ããªããã£ããšåæ§ã«ãçŸåšã®ã¹ã¬ããã®å®è¡ããããã¯ããåã«äžæçã«ã¹ãã³ããã¯ããã£ããã£ã§ããŸãã ãã®ããªããã£ããå®è£ ããã«ã¯ã2ã€ã®ã»ããã©ãå¿ èŠã§ãã1ã€ã¯ãªãŒããŒãæåŸ ããããããã1ã€ã¯ã©ã€ã¿ãŒã®ããã§ãã
4.é£äºããå²åŠè ã®åé¡
èè¡åå ¥ãã¿ãŒã³ã䜿çšãããšããããŸã§èŠãããšã®ãªãããªãçããæ¹æ³ã§ãå²åŠè ã®é£äºã®åé¡ã解決ã§ããŸãã ææ¡ããããœãªã¥ãŒã·ã§ã³ã誰ã«ãšã£ãŠãæçšã§ãããšã¯æããªãã®ã§ãå®è£ ã®è©³çŽ°ã«ã¯è§ŠããŸããã ã»ããã©ã®æ®éæ§ã瀺ãããã«ããã®ããªããã£ãã®èª¬æãå«ããŸããã
ãã®ãããåå²åŠè ïŒã¹ããªãŒã ïŒã«ç¬èªã®ã»ããã©ãå²ãåœãŠãŸãã ãã±ãã売ãå Žã¯ãã©ã®å²åŠè ãçŸåšé£ã¹ãŠããããã©ã®å²åŠè ãé£äºãéå§ããããã«èŠæ±ããããããã³ãããã®èŠæ±ã®ã·ãŒã±ã³ã¹ãç£èŠããŸãã ãã®æ å ±ã¯ãèè¡äŒç€Ÿããã¹ãŠã®å²åŠè ã«æé©ãªæ¹æ³ã§åãä»ããããã»ããã©ãå°ãã®ã«ååã§ãã
2ã€ã®å®è£ ãææ¡ããŸããã ãããã®1ã€ã¯DiningPhilosophersã§ã ãããã¯ããã¥ãŒããã¯ã¹ã䜿çšããŠèè¡åå ¥ãå®è£ ããŸãã 2ã€ç®ã¯LockReducedDiningPhilosophers㧠ãããã¯ã¹ãªãã£ã¹ãžã®ååŒã³åºãã¯ããã¯ããªãŒã¢ã«ãŽãªãºã ãšããŠå®è£ ãããŸãã
5.軜éã»ããã©
ã¯ããããã§ããèè¡åå ¥ãã¿ãŒã³ãšã»ããã©ã®å©ããåããŠãå¥ã®ã»ããã©ãå®è£ ã§ããŸãã
ãªããããããªããã°ãªããªãã®ã§ããïŒ ãªããªãLightweightSemaphoreãååŸããããã§ãã ãã®ãããªã»ããã©ã«ã¯ãåŸ æ©äžã®ã¹ã¬ããããã¥ãŒã«ãªãå Žåã®ã·ã°ãã«æäœãéåžžã«å®äŸ¡ã§ãã ããã«ãOSãæäŸããã»ããã©ã®å®è£ ã«äŸåããŸããã ã·ã°ãã«ãåŒã³åºããããšãèè¡åå ¥ã¯ ãåºç€ãšãªãã»ããã©ã«é Œãããšãªããç¬èªã®å éšã«ãŠã³ã¿ã®å€ãå¢ãããŸãã
ããã«ãã«ãŒãå ã§ã¹ã¬ããããã°ããåŸ æ©ãããŠããããããã¯ããããšãã§ããŸãã ãã®ããªãã¯ã«ãããåŸ æ©æéãäºåå®çŸ©ãããå€ãããçãå Žåã«ãã·ã¹ãã ã³ãŒã«ã«é¢é£ãããªãŒããŒããããæžããããšãã§ããŸãã
GitHubãªããžããªã§ã¯ããã¹ãŠã®ããªããã£ãã¯LightweightSemaphoreã«åºã¥ããŠããŸãã ãã®ã¯ã©ã¹ã¯ãç¹å®ã®OSã«ãã£ãŠæäŸãããã»ããã©ã«åºã¥ããŠå®è£ ãããŠããSemaphoreã«åºã¥ããŠå®è£ ãããŠããŸãã
Windows PCã§LightweightSemaphoreãšSemaphoreã䜿çšãããšãã«ãæ瀺ãããããªããã£ãã®é床ãæ¯èŒããããã«ããã€ãã®ãã¹ããå®è¡ããŸããã 察å¿ããçµæãè¡šã«ç€ºããŸãã
軜éã»ããã© | ã»ããã© | |
---|---|---|
testBenaphore | 375ããªç§ | 5503ããªç§ |
testRecursiveBenaphore | 393ããªç§ | 404ããªç§ |
testAutoResetEvent | 593ããªç§ | 4665ããªç§ |
testRWLock | 598ããªç§ | 7126ããªç§ |
testDiningPhilosophers | 309ããªç§ | 580ããªç§ |
ã芧ã®ãšãããåäœæéã¯æ¡éãã«ç°ãªãå ŽåããããŸãã ç§ã¯èšããªããã°ãªããªããç§ã¯ãã¹ãŠã®ç°å¢ãåããŸãã¯åæ§ã®çµæãæã€ããã§ã¯ãªãããšãèªèããŠããŸãã çŸåšã®å®è£ ã§ã¯ãã¹ã¬ããã¯ã«ãŒãã®10,000åã®å埩ãåŸ ã£ãŠããã»ããã©ãããã¯ããŸãã é©å¿ã¢ã«ãŽãªãºã ã䜿çšããå¯èœæ§ã«ã€ããŠç°¡åã«æ€èšããŸããããæè¯ã®æ¹æ³ã¯èªæã§ã¯ãªãããã«æãããŸããã ã ããç§ã¯ææ¡ãåãå ¥ããŠããŸãã
ã»ããã©ãšæ¡ä»¶å€æ°ã®æ¯èŒ
ã»ããã©ã¯ãäºæ³ãããã¯ããã«æçšãªããªããã£ãã§ããããšãå€æããŸããã ã§ã¯ããªãC ++ 11 STLã«æ¬ ããŠããã®ã§ããïŒ Boostã«ååšããªãã£ãã®ãšåãçç±ã§ããã¥ãŒããã¯ã¹ãšæ¡ä»¶å€æ°ãåªå ãããŸããã ã©ã€ãã©ãªéçºè ã®èŠ³ç¹ããã¯ãåŸæ¥ã®ã»ããã©ã®äœ¿çšã¯ãã°ãã°ãšã©ãŒã«ã€ãªãããŸãã
èããŠã¿ããšãããã¯ã¹ãªãã£ã¹ãã¿ãŒã³ã¯ãæ¡ä»¶å€æ°ã®ãã¹ãŠã®æäœãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã®æåŸã§å®è¡ãããå Žåã®ãéåžžã®æ¡ä»¶å€æ°ã®æé©åã«ãããŸããã AutoResetEventã¯ã©ã¹ãæ€èšããŠãã ããã åãåäœã§AutoResetEventCondVarã¯ã©ã¹ãå®è£ ããŸããããstdïŒcondition_variableã䜿çšããŸããã æ¡ä»¶å€æ°ã®ãã¹ãŠã®æäœã¯ãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã®æåŸã«å®è¡ãããŸãã
void AutoResetEventCondVar::signal() { // Increment m_status atomically via critical section. std::unique_lock<std::mutex> lock(m_mutex); int oldStatus = m_status; if (oldStatus == 1) return; // Event object is already signaled. m_status++; if (oldStatus < 0) m_condition.notify_one(); // Release one waiting thread. }
ãã®æ¹æ³ã¯ã2ã€ã®å埩ã§æé©åã§ããŸãã
- ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ããåæ¡ä»¶å€æ°ãåãåºããŠãã»ããã©ã«å€æããŸãã ã·ã°ãã«ã®ç¬ç«æ§-ã»ããã©ã«å¯Ÿããæäœã®åŸ æ©ã·ãŒã±ã³ã¹ã«ããããã®æé©åãå¯èœã«ãªããŸãã ãã®ã¹ãããã®åŸããã®ã¡ãœããã®å®è£ ã¯ãã§ã«èè¡åå ¥ãã¿ãŒã³ã®å®è£ ã«äŒŒãŠããŸãã
- ããã§ããã¹ãŠã®æäœãCASã«çœ®ãæããŠããã¯ããªãŒæ¹åŒãå®çŸã§ãããããã·ã¹ãã ã®ã¹ã±ãŒã©ããªãã£ãå€§å¹ ã«åäžããŸãã
ããã2ã€ã®åçŽãªæé©åã®åŸãAutoResetEventãååŸããŸãã
ç§ã®Windows PCã§ã¯ãAutoResetEventCondVarãAutoResetEventã«çœ®ãæããã ãã§ãã¢ã«ãŽãªãºã ã®é床ã10åã«ãªããŸãã
翻蚳è ããïŒç§ã¯é·ãéäœã翻蚳ããŠããªãã®ã§ãèšæ£ãšèª¬æã«æè¬ããŸãã