ãããããã¯ç¶æ³
ãŠã£ãããã£ã¢ã§ã¯ããããããã¯ã®æ¬¡ã®å®çŸ©ãæäŸããŠããŸããããããããã¯ïŒEngãDeadlockïŒ-ãã«ãã¿ã¹ã¯ç°å¢ãŸãã¯DBMSã®ç¶æ³ãè€æ°ã®ããã»ã¹ãããããã®ããã»ã¹èªäœãå æãããªãœãŒã¹ãç¡éã«åŸ æ©ããŠããç¶æ ã§ããã
çžäºããã¯ã¯éåžžãæ¬è³ªçã«åçã§ãããããã®å åã¯ããŠãŒã¶ãŒã¢ã¯ã·ã§ã³ããããã¯ãŒã¯ãµãŒãã¹ã®å¯çšæ§ãããŒããã©ã€ãã®ãããã®äœçœ®ãããªãšã³ããã£ããã«ãã¿ã¹ã¯ãåããã·ã¹ãã ã§ã®ã¿ã¹ã¯åãæ¿ããªã©ã®èŠå ã«äŸåããŸãã
ãããããã¯ã®å žåçãªäŸïŒæåã®ã¹ã¬ããïŒAïŒã¯ãã¥ãŒããã¯ã¹M1ããã£ããã£ãã次ã«ãã¥ãŒããã¯ã¹M2ããã£ããã£ããŸãã 2çªç®ã®ã¹ã¬ããïŒBïŒã¯M2ãã¥ãŒããã¯ã¹ããã£ããã£ãããã®åŸãM1ãã¥ãŒããã¯ã¹ããã£ããã£ããŸãã ããã2ã€ã®ã¹ããªãŒã ã®çžäºãããã¯ã¯ã次ã®ããã«çºçããŸããã¹ããªãŒã Aã¯M1ããã£ããã£ããã¹ããªãŒã Bã¯M2ããã£ããã£ããŸãããã®åŸãäž¡æ¹ã®ã¹ããªãŒã ããæ¡å€§ããããŸãã ãã¥ãŒããã¯ã¹ããã£ããã£ããããšãããšãäž¡æ¹ã®ã¹ã¬ããããããã¯ãããŸãã
説æãããŠããçžäºããã¯ã¯ãäž¡æ¹ã®ã¹ã¬ããã1ã€ã®ãã¥ãŒããã¯ã¹ãæ£ç¢ºã«ãã£ããã£ããæéãããå Žåã«ã®ã¿çºçããŸãã ãã以å€ã®å Žåãã¹ã¬ããã¯å®è¡ãç¶ç¶ããŸãã
ãã®ç¶æ³ã¯ãè€éãªãã«ãã¹ã¬ããã·ã¹ãã ã§ã¯éåžžã«äžè¬çã§ãã ååãšããŠãåå è ãã¥ãŒããã¯ã¹ã¯äºãã«é¢ããŠïŒã·ã¹ãã ã®ããŸããŸãªã³ã³ããŒãã³ãã§ïŒé 眮ãããçžäºãããã¯ã®åå è ãèå¥ããããšã¯ããªãå°é£ã§ãã
å®éã®ã·ã¹ãã ã®äžè¬çãªç¶æ³
äžèšã®ãããããã¯ãçºçããç¹æ®ãªã±ãŒã¹ã®1ã€ã¯æ¬¡ã®ãšããã§ãã
- ç¹å®ã®ãªããžã§ã¯ãïŒã¯ãŒã«ãŒïŒã¯ãå¥ã®ã¹ã¬ããã§äœããã®ã¢ã¯ãã£ããã£ãå®è¡ããŸãã Workerãªããžã§ã¯ãã¯ããã®ååšã®éå§æã«ãã®ã¹ããªãŒã ãäœæããããèªäœãç Žæ£ãããåã«å®äºããŸãã
- ãããŒã¢ã¯ãã£ããã£ã¯ãç¹å®ã®ã¢ã¯ã·ã§ã³ã®åšæçãªç¹°ãè¿ãã§æ§æãããŸãïŒããšãã°ããããã¯ãŒã¯ããã®ããŒã¿ã®åä¿¡ïŒã
- ãããã®åã ã®ã¢ã¯ã·ã§ã³ã®çµæã¯ãé¢æ°ãŸãã¯ã³ãŒã«ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ãéããŠã³ã³ââã·ã¥ãŒãã«æäŸãããŸãã
- Workerãªããžã§ã¯ãã®å¯¿åœã®ã©ã®æç¹ã§ããæ°ããæ¶è²»è ã衚瀺ãããããæ¢åã®æ¶è²»è ã衚瀺ãããªããªãå ŽåããããŸãã Workerãªããžã§ã¯ãã¯ãã³ã³ã·ã¥ãŒããŒã®ãªã¹ããä¿æããã³ã³ã·ã¥ãŒããŒãç»é²ããã³åé€ããããã®æ©èœïŒããããregisterCallbackããã³unregisterCallbackïŒãæäŸããŸãã
- ã³ã³ã·ã¥ãŒãã®ãªã¹ãã¯å ±æãªãœãŒã¹ã§ããWorkerãªããžã§ã¯ãã®å éšã¹ããªãŒã ã¯ããã«ã¢ã¯ã»ã¹ã§ããŸãããŸããã¹ããªãŒã ã®ã³ã³ããã¹ãããregisterCallbackãšunregisterCallbackãåŒã³åºãã³ã³ã·ã¥ãŒããåæ§ã§ãã
- ã³ã³ã·ã¥ãŒãã®ãªã¹ãã¯å ±æãªãœãŒã¹ã§ãããããWorkerãªããžã§ã¯ããææãããã¥ãŒããã¯ã¹ã䜿çšããŠä¿è·ãããŸãã ãã¥ãŒããã¯ã¹ããã£ããã£ããããšãã³ã³ã·ã¥ãŒãã®ãªã¹ããå€æŽãããŸãã ãã¥ãŒããã¯ã¹ããã£ããã£ããããšãããŒã¿ã¯Workerãªããžã§ã¯ãããã³ã³ã·ã¥ãŒãã«è»¢éãããŸãã
äžèšã®ç¶æ³ã¯ãªãå±éºãªã®ã§ããïŒ Workerãªããžã§ã¯ãã®éçºæ®µéã§ã¯ãéçºè ã¯ã³ãŒã«ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠã·ã¹ãã ã®ã©ã®é¢æ°ãåŒã³åºããããããŸã ç¥ããŸããã§ããã 圌ã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®èŠä»¶ã®ã¿ãäœæããŸãããé¢æ°ã«ã¯ããã®ãããªããŒã¿ãéä¿¡ãããããã®ãã©ã¡ãŒã¿ãå¿ èŠã§ãã ãããŠããã®æªç¥ã®æ¹åãžã®ææŠã¯ããã£ããã£ããããã¥ãŒããã¯ã¹ã«ãã£ãŠè¡ãããŸãã
説æããç»åã«ããã€ãã®ã¿ãããè¿œå ããã ãã§ååã§ãïŒããã¯è€éãªã·ã¹ãã ã§çºçããããšã§ãïŒã
- Workerãªããžã§ã¯ãã®ããããã®ã³ã³ã·ã¥ãŒããŒå ã§ãmutex Mããã£ããã£ãŒãããŸãïŒãã¡ããããã®åŸã®ãªãªãŒã¹ã§ïŒã
- ãã£ããã£ãããMutex Mãæã€å¥ã®ã·ã¹ãã ãªããžã§ã¯ãã¯ãèªèº«ãWorkerãªããžã§ã¯ãã®ã³ã³ã·ã¥ãŒããšããŠç»é²ããŸãã
ããã ãã§ã ãããããã¯ãçºçããå¯èœæ§ãããç¶æ³ãå€æããŸããã 100ïŒ ã®ã±ãŒã¹ã§ã¯çºçããŸããïŒåå ããåã¹ã¬ããã1ã€ã®ãã¥ãŒããã¯ã¹ã®ã¿ããã£ããã£ããããã«ç¹å®ã®ãã€ããã¯ã¹ãå¿ èŠã§ãïŒãããã«ããããã®ãããªãšã©ãŒã®æ€çŽ¢ãå€§å¹ ã«è€éã«ãªããŸãã
以äžã¯ããã®åé¡ã解決ãã2ã€ã®æ¹æ³ã§ãã
æ¹æ³1ïŒããã¯ã®é åºãå€æŽãã
Workerãªããžã§ã¯ãã¯ãå éšãã¥ãŒããã¯ã¹ãããã¯ããã³ããã¯è§£é€ããããã®åå¥ã®æ©èœãæäŸããã³ã³ã·ã¥ãŒããŒã¯æ¬¡ã®ããã«ç»é²ããŸãã
- æåïŒäºåã«ïŒãWorkerãªããžã§ã¯ãã®å éšãã¥ãŒããã¯ã¹ãããã¯ãããŸãã
- ãã®åŸãã³ã³ã·ã¥ãŒãã¯ãã¥ãŒããã¯ã¹Mã®ãã£ããã£ãå¿ èŠãšããã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
- ã³ã³ã·ã¥ãŒããŒã¯Workerãªããžã§ã¯ãã«ç»é²ããŸãã Workerãªããžã§ã¯ãå ã®å éšãã¥ãŒããã¯ã¹ã®ãã£ããã£ã¯å®è¡ãããŸããã
ãã®æ¹æ³ã®æ¬ ç¹ã¯æããã§ãã
- åã³ã³ã·ã¥ãŒããŒã¯ãWorkerãªããžã§ã¯ããæäœããåã«äºåçãªã¢ã¯ã·ã§ã³ã®è² æ ããããŸãã ããã°ã©ããŒåŽã®ãšã©ãŒã®ç¢ºçãå¢å ããŸãã
- ããã¯åžžã«å¯èœãªããã§ã¯ãããŸãããMutexMãWorkerãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãžã®å®å šãªã¢ã¯ã»ã¹ãæäŸããå Žåã¯ã©ããªããŸããïŒ
- ãã¬ããã¢ãŠããã¯simplyãã ãã§ãã
æ¹æ³2ïŒããŒã¿ãã³ã³ã·ã¥ãŒããŒã«éä¿¡ãããšãã«ãã¥ãŒããã¯ã¹ããããã¯ããªã
ãã®ã¡ãœããã¯ææã«èãããŸããmutexããããã¯ãããŠããªããšãã«Workerãªããžã§ã¯ãã®å éšã¹ããªãŒã ããã³ã³ã·ã¥ãŒããŒãžã®ããŒã¿è»¢éãçºçããå ŽåãWorkerãªããžã§ã¯ããæäœãããšãã«èµ·ãããããã¹ãŠã®çžäºããã¯ãä¿®æ£ãããŸãã
ãã¥ãŒããã¯ã¹ããã£ããã£ãããªããšãã«ã³ãŒã«ããã¯ãäœæããªãã®ã¯ãªãã§ããïŒ Workerãªããžã§ã¯ãã¹ããªãŒã ã¯ãç»é²ãããã³ã³ã·ã¥ãŒããŒã®ãªã¹ãã調ã¹ãŠãåã³ã³ã·ã¥ãŒããŒã®ã€ã³ã¿ãŒãã§ã€ã¹é¢æ°ãåŒã³åºãå¿ èŠãããããã§ãã ãªã¹ãããã¥ãŒããã¯ã¹ã«ãã£ãŠä¿è·ãããŠãããããã®ãµã€ã¯ã«äžã«ãªã¹ãã®å 容ãå€æŽããããšã誀ã£ãã¡ã¢ãªã¢ã¯ã»ã¹ã«ããããã°ã©ã ãã«ãŒãããããã¯ã©ãã·ã¥ãããããå¯èœæ§ããããŸãã
æ¶è²»è ã®ãªã¹ãã®ã³ããŒãäœæããŠïŒã³ããŒãäœæãããšãããã¥ãŒããã¯ã¹ãååŸããïŒãã³ããŒãã«ãŒãããŸãããïŒ unregisterCallbackãåŒã³åºããåŸãããŒã¿ã転éãããªãããšãæ¶è²»è ã«ä¿èšŒããå¿ èŠãããããã§ãã ã³ã³ã·ã¥ãŒãããã¹ãã©ã¯ã¿ããunregisterCallbackãåŒã³åºããšããã®ã³ã³ã·ã¥ãŒãã®ã³ãŒã«ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ãžã®åŸç¶ã®ããŒã¿è»¢éã«ãããããã°ã©ã ãã¯ã©ãã·ã¥ããŸãã
ãããã£ãŠãç§ãã¡ã¯ã»ãšãã©æ±ºå®ã«éããŸããïŒ
- ç»é²ãããã³ã³ã·ã¥ãŒããŒã®ã€ã³ã¿ãŒãã§ã€ã¹ãåŒã³åºãåã«ã¯ãŒã«ãŒãªããžã§ã¯ãã¹ããªãŒã ã¯ãã³ã³ã·ã¥ãŒããŒã®ãªã¹ãã®ã³ããŒãäœæããå¿ èŠããããŸãã ãã¥ãŒããã¯ã¹ããã£ããã£ããããšã³ããŒãäœæãããã³ã³ã·ã¥ãŒãã«ããŒã¿ãéä¿¡ããããã«ãã¹ããªãŒã ã¯ãªã¹ãã®ã³ããŒãã«ãŒãããŸãã
- unregisterCallbackåŒã³åºããå®äºããåŸãã³ã³ã·ã¥ãŒãã«ããŒã¿ãéä¿¡ãããªãããã«ããå¿ èŠããããŸãã ã¹ããªãŒã ããã³ã³ã·ã¥ãŒããŒãžã®åŒã³åºãããšã«ã³ã³ã·ã¥ãŒããŒãªã¹ãã®ã³ããŒãäœæããããããã³ã³ã·ã¥ãŒããŒãªã¹ãã®ã³ããŒã®ééäžã«unregisterCallbackãåŒã³åºãããå Žåããé 延åŒã³åºããã®ãªã¹ã¯ã¯1åã ãååšããŸãã
- ãããã£ãŠãWorkerãªããžã§ã¯ãã¹ããªãŒã ãã³ã³ã·ã¥ãŒãã«ããŒã¿ã転éããã³ã³ã·ã¥ãŒãã®ãªã¹ãã®ã³ããŒãåŠçãããšãã®ç¶æ ãäœããã®æ¹æ³ã§èå¥ããå¿ èŠããããŸãã ã¹ããªãŒã ããã®ç¶æ ã«ãããšãã«unregisterCallbackãåŒã³åºãããå ŽåãunregisterCallbackããã®æ»ãã¯ãã³ã³ã·ã¥ãŒããžã®ããŒã¿è»¢éãå®äºãããŸã§é 延ããå¿ èŠããããŸãã
ãããã¿ãŒã³ããŒãœãªã¥ãŒã·ã§ã³ã§ãã ãã®å®è£ ã«ã¯ããã1ã€ã®åæãªããžã§ã¯ããå¿ èŠã§ã-ãæ¡ä»¶å€æ°ãïŒè±èªã®æ¡ä»¶å€æ°ïŒïŒ
- Workerãªããžã§ã¯ãã«ã¯æ¬¡ãå«ãŸããŸãã
- æ¶è²»è ã®ãªã¹ãã
- ã¹ããªãŒã ãçŸåšããŒã¿ãã³ã³ã·ã¥ãŒãã«éä¿¡ããŠããããšã瀺ããã©ã°ã
- æ¶è²»è ã®ãªã¹ããšãã©ã°ãžã®ã¢ã¯ã»ã¹ãå¶éãããã¥ãŒããã¯ã¹ã
- unregisterCallbackããéã«åããªãããšåŒãã æ¶è²»è ã®æåŸ ãšç®èŠããæŽçããããã®æ¡ä»¶å€æ°ã
- ãã©ã°ã¯æåã«falseã«åæåãããŸãã
- registerCallbackã¯ãã¥ãŒããã¯ã¹ããã£ããã£ãããªã¹ãã«ã³ã³ã·ã¥ãŒããè¿œå ããŠããã¥ãŒããã¯ã¹ã解æŸããŸãã
- æ¶è²»è
ãžã®ããŒã¿è»¢éãµã€ã¯ã«ã®åã«ã¹ããªãŒã ã¯æ¬¡ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
- ãã¥ãŒããã¯ã¹ããã£ããã£ããŸãã
- æ¶è²»è ã®ãªã¹ãã®ã³ããŒãäœæããŸãã ã¹ããªãŒã ã¹ã¿ãã¯ã«ã³ããŒãäœæãããŸãã
- ãã©ã°ãtrueã«èšå®ããŸãã
- ãã¥ãŒããã¯ã¹ã解æŸããŸãã
- ã¹ããªãŒã ã¯ããŒã¿ãæ¶è²»è ã«è»¢éããæ¶è²»è ãªã¹ãã®ã³ããŒã®ãµã€ã¯ã«ãééããŸãã ãã¥ãŒããã¯ã¹ã¯ãã£ããã£ãããŸãããããã©ã°ã¯èšå®ãããŸãã
- ããŒã¿ãã³ã³ã·ã¥ãŒãã«éä¿¡ããåŸãã¹ããªãŒã ã¯æ¬¡ã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãã
- ãã¥ãŒããã¯ã¹ããã£ããã£ããŸãã
- ãã©ã°ãfalseã«ãªã»ããããŸãã
- æ¡ä»¶å€æ°ã䜿çšããŠãã¹ãŠã®ä¿çäžã®ã¹ã¬ãããèµ·åããŸãã
- ãã¥ãŒããã¯ã¹ã解æŸããŸãã
- ããã³-æãèå³æ·±ã-unregisterCallbackïŒ
- ãã¥ãŒããã¯ã¹ããã£ããã£ããŸãã
- ãªã¹ãããã³ã³ã·ã¥ãŒããŒãåé€ããŸãã
- ãã©ã°ãèšå®ãããŠããéããæ¡ä»¶å€æ°ã§åŸ æ©ããŸãã ã¢ãããã¯ã«ããã¥ãŒããã¯ã¹ã¯åŸ æ©ç¶æ ãžã®ç§»è¡ãšãšãã«ãªãªãŒã¹ããããã¥ãŒããã¯ã¹ã¯ç®èŠããšãšãã«ã¢ãããã¯ã«ãã£ããã£ãããŸãã
- ãã¥ãŒããã¯ã¹ã解æŸããŸãã
éèŠãªæ³šæïŒã³ã³ã·ã¥ãŒããŒã«ãã£ãŠå®è£ ãããã³ãŒã«ããã¯ã€ã³ã¿ãŒãã§ã€ã¹ããunregisterCallbackãåŒã³åºãããšãã§ããå Žåã説æãããŠããã¢ã«ãŽãªãºã ã¯unregisterCallbackå ã§100ïŒ ããªãŒãºããŸãã ããã¯ç°¡åã«è§£æ±ºã§ããŸããunregisterCallbackãWorkerãªããžã§ã¯ãã®å éšã¹ã¬ããã®ã³ã³ããã¹ãã§åŒã³åºãããå Žåããã©ã°ã確èªããŠæ¡ä»¶å€æ°ãå€åããã®ãåŸ ã€å¿ èŠã¯ãããŸããã
Qtã©ã€ãã©ãªåæããŒã«ã䜿çšããå®è£
ããããŒãã¡ã€ã«ïŒ
class ICallback { public: virtual void dataReady(QByteArray data) = 0; }; class Worker : public QThread { public: Worker(); void registerCallback(ICallback *callback); void unregisterCallback(ICallback *callback); protected: virtual void run(); private: QMutex _mutex; QWaitCondition _wait; bool _callingNow; QLinkedList<ICallback *> _callbacks; };
å®è£ ïŒ
Worker::Worker() : QThread(), _mutex(QMutex::NonRecursive), _callingNow(false) { ... } void Worker::registerCallback(ICallback *callback) { QMutexLocker locker(&_mutex); _callbacks.append(callback); } void Worker::unregisterCallback(ICallback *callback) { QMutexLocker locker(&_mutex); _callbacks.removeOne(callback); if(QThread::currentThread()!=this) { while(_callingNow) _wait.wait(&_mutex); } } void Worker::run() { while(...) { QByteArray data; ... QLinkedList<ICallback *> callbacksCopy; _mutex.lock(); _callingNow=true; callbacksCopy=_callbacks; _mutex.unlock(); for(QLinkedList<Callback *>::const_iterator it=callbacksCopy.begin(); it!=callbacksCopy.end(); ++it) { (*it)->dataReady(data); } _mutex.lock(); _callingNow=false; _wait.wakeAll(); _mutex.unlock(); } }