C++11æ¨æºã©ã¤ãã©ãªã®std::mutex
ãªãã¸ã§ã¯ãã§ã¯ãããã¯åå¾ï¼è§£æ¾ãåä¸ã¹ã¬ãã*1ããè¡ããªããã°ãªããªããï¼N3337 30.2.5.2/p3ï¼
m.unlock()
Requires: The current execution agent shall hold a lock onm
.
ãã®å¶ç´æ¡ä»¶ã®ãããä¸è¨ã³ã¼ãã®mutexãªãã¸ã§ã¯ãå©ç¨ã¯æªå®ç¾©åä½(undefined behavior)ãå¼ãèµ·ããã
#include <thread> #include <mutex> std::mutex mtx; // mutexãªãã¸ã§ã¯ã int resource; // ä¿è·å¯¾è±¡ã®ãªã½ã¼ã¹ void proc() { // resourceã使ãå¦çB mtx.unlock(); // (2) NGï¼å¥ã¹ã¬ããã§ããã¯è§£æ¾...ããã //... } int main() { mtx.lock(); // (1) ã¡ã¤ã³ã¹ã¬ããã§ããã¯ç²å¾ // resourceã使ãå¦çA std::thread th(proc); //... }
ä¸è¬çã«ãã¥ã¼ããã¯ã¹ã¯ãã¹ã¬ããã«ããææããããè¨è¨ã¨ãªã£ã¦ãããã*2ãããã¯ææ権ã®åå¾ï¼è§£æ¾ãç°ãªãã¹ã¬ããããè¡ããã¨ã¯åºæ¥ãªããPOSIX(pthread)ãWindows APIãBoost.Threadã©ã¤ãã©ãªããããã®ãã¥ã¼ããã¯ã¹ã§ãåãå¶ç´ãåå¨ãã*3ã
- POSIXï¼pthread_mutex_unlock()
- Windows APIï¼ReleaseMutex()ããã³LeaveCriticalSection()
- Boost.Threadï¼Lockable Concept; void unlock()
ãã®åé¡ã¯ã»ããã©(semaphore)ãå©ç¨ãã¦åé¿ã§ãããç¹ã«mutexç¸å½ã®æä»å¶å¾¡ãè¡ãã ãã§ããã°ããã¤ããªã»ããã©(binary semaphore)ã§ååç®çãæãããã
binsem sem; // binary semaphoreãªãã¸ã§ã¯ã int resource; // ä¿è·å¯¾è±¡ã®ãªã½ã¼ã¹ void proc() { // resourceã使ãå¦çB sem.unlock(); // (2) å¥ã¹ã¬ããã§è§£æ¾(Væä½) //... } int main() { sem.lock(); // (1) ã¡ã¤ã³ã¹ã¬ããã§ç²å¾(Pæä½) // resourceã使ãå¦çA std::thread th(proc); //... }
ä¸è¨ã³ã¼ãã§ã¯mutexã®ä»£ããã«ãã¤ããªã»ããã©binsemãç¨ãã¦æä»å¶å¾¡ãè¡ã£ã¦ããããã ããresourceã使ãå¦çA, Bããä¾å¤ã¹ãã¼ãããå ´åã¯ã»ããã©è§£æ¾å¦çãè¡ããããåã»ããã©ãç²å¾ãããã¨ããä»ã¹ã¬ãããæ°¸é ã«ãããã¯ãããå±éºæ§ããããbinsemã¯ã©ã¹ãLockableåã®è¦ä»¶*4ãæºããã¦ããã°ãstd::unique_lock
ã«ããããã¯ä¿ææ©æ§ã§ä¾å¤å®å
¨ãªã³ã¼ããè¨è¿°ã§ããã
void proc(std::unique_lock<binsem> lk) { // resourceã使ãå¦çB lk.unlock(); // (2) å¥ã¹ã¬ããã§è§£æ¾ //... } int main() { std::unique_lock<binsem> lk; // (1) ã¡ã¤ã³ã¹ã¬ããã§ç²å¾ // resourceã使ãå¦çA std::thread th(proc, std::move(lk)); //... }
C++11æ¨æºã©ã¤ãã©ãªãç¨ãããã¤ããªã»ããã©binsemã¯ã©ã¹ã®å®è£
ã¯ä¸è¨ã®éããåã¯ã©ã¹ã¯Lockableè¦ä»¶ãæºããã
*1:ããã¯ã«é¢ããC++11ä»æ§ã«ããã¦ã¯ "thread" ã§ã¯ãªããããä¸è¬åãã "execution agent" ã¨ããç¨èªãç¨ããããã"An execution agent is an entity such as a thread that may perform work in parallel with other execution agents."ï¼N3337 30.2.5.1/p1ï¼
*2:ä¸è¬å®ç¾©ã«ã¤ãã¦ã¯wikipedia:en:Mutual_exclusionãwikipedia:ja:æä»å¶å¾¡ããããåç §ãã¾ããããã§ã¯åä¸ããã»ã¹å ã®ã¹ã¬ããéæä»å¶å¾¡ã®ã¿ã対象ã¨ãã¦ããã
*3:Windows APIã§ã¯CriticalSectionã¨Mutexãç°ãªãåæããªããã£ãã¨ãã¦æ±ãããæ¬è¨äºã®æèã§ã¯ä¸¡è ã¯åãæä»å¶å¾¡ãå®ç¾ããæ©è½ã¨ã¿ãªããããããWindows APIã§ã®ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³(critical section)ã®ç¨æ³ãä¸è¬å®ç¾©ã¨ç°ãªãæ··ä¹±ãæãã¦ãã...
*4:N3337 30.2.5ã«ã¦BasicLockable, Lockable, TimedLockableã®3種é¡ãå®ç¾©ããããåè¦ä»¶ã«ã¯å å«é¢ä¿ããããå¾è ã»ã©ä»æ©è½ã