ãã®èšäºã§ã¯ãstd :: threadã®åé¡ã«å¯ŸåŠãããpthread_cancelãboolean flagãŸãã¯boost :: thread :: interruptïŒããšãããããã¯ã«é¢ããå€ä»£ã®è°è«ãåæã«è§£æ±ºããŸãã
åé¡
C ++ 11ã§è¿œå ãããstd :: threadã¯ã©ã¹ã«ã¯ã1ã€ã®äžå¿«ãªæ©èœããããŸããããã¯ã RAIIã€ãã£ãªã ïŒResource Acquisition Is InitializationïŒã«å¯Ÿå¿ããŠããŸããã æšæºããã®æç²ïŒ
30.3.1.3ã¹ã¬ãããã¹ãã©ã¯ã¿
ãã¹ã¬ããïŒïŒ;
joinableïŒïŒã®å Žåã¯terminateïŒïŒ ããã以å€ã®å Žåã¯å¹æã¯ãããŸããã
ãã®ãããªãã¹ãã©ã¯ã¿ã§ç§ãã¡ãè
ãããã®ã¯äœã§ããïŒ ããã°ã©ãã¯ã std::thread
ãªããžã§ã¯ããç Žæ£ããéã«éåžžã«æ³šæããå¿
èŠããããŸãã
void dangerous_thread() { std::thread t([] { do_something(); }); do_another_thing();
do_another_thing
颿°ããäŸå€ãã¹ããŒãããå Žåã std::thread
destructorã¯std::terminate
åŒã³åºããŠããã°ã©ã å
šäœãstd::terminate
ã ããã§äœãã§ããŸããïŒ std::thread
åšãã«RAIIã©ãããŒãæžããŠã¿ãŠããã®è©Šã¿ãç§ãã¡ãã©ãã«é£ããŠè¡ããèŠãŠã¿ãŸãããã
RAIIãstdã«è¿œå ::ã¹ã¬ãã
class thread_wrapper { public:
thread_wrapper
ã¯ã std::thread
ã€ã³ã¿ãŒãã§ãŒã¹ãã³ããŒããå¥ã®è¿œå ã®é¢æ°reset
ãå®è£
ããŸãã ãã®é¢æ°ã¯ãã¹ã¬ãããçµåäžå¯èœãªç¶æ
ã«ããå¿
èŠããããŸãã ãã¹ãã©ã¯ã¿ã¯ãã®é¢æ°ãåŒã³åºãããããã®åŸ_impl
std::terminate
ãåŒã³åºãã_impl
æãããã¿std::terminate
ã
_impl
ãéçµåç¶æ
ã«ããããã«ã reset
ã¯detach
ãŸãã¯join
2ã€ã®ãªãã·ã§ã³ããããŸãã detach
ã®åé¡ã¯ãã¹ã¬ãããåŒãç¶ãå®è¡ãããæ··ä¹±ãåŒãèµ·ãããRAIIã€ãã£ãªã ã«éåããããšã§ãã ã ããç§ãã¡ã®éžæã¯join
ã§ãïŒ
thread_wrapper::reset() { if (joinable()) join(); }
æ·±å»ãªåé¡
æ®å¿µãªããã thread_wrapper
ãã®ãããªå®è£
ã¯ãéåžžã®std::thread
ãããåªããŠãstd::thread
ã ãªãã§ïŒ 次ã®äœ¿çšäŸãèŠãŠã¿ãŸãããã
void use_thread() { std::atomic<bool> alive{true}; thread_wrapper t([&alive] { while(alive) do_something(); }); do_another_thing(); alive = false; }
do_another_thing
ããäŸå€ãdo_another_thing
ããå Žåãç°åžžçµäºã¯çºçããŸããã ãã ãã alive
ãfalse
ã«ãªãããšã¯ãªããã¹ã¬ããã¯çµäºããªãããã thread_wrapper
ãã¹ãã©ã¯ã¿ãŒããã®join
åŒã³åºãã¯æ°žä¹
ã«thread_wrapper
ãŸã ã
åé¡ã¯ã thread_wrapper
ãªããžã§ã¯ãthread_wrapper
ãå®è¡äžã®é¢æ°ã«åœ±é¿ãäžããŠå®äºããæ±ãããæ¹æ³thread_wrapper
ãªãããšã§ãã do_something
颿°ã§ã¯ãå®è¡ã¹ã¬ãããæ¡ä»¶å€æ°ãŸãã¯ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ãããã¯åŒã³åºãã§ãã¹ãªãŒããç¶æ
ã«ãªãå¯èœæ§ããããããç¶æ³ã¯ããã«è€éã«ãªããŸãã
ãããã£ãŠã std::thread
ãã¹ãã©ã¯ã¿ã§åé¡ã解決ããã«ã¯ãããæ·±å»ãªåé¡ã解決ããå¿
èŠããããŸãã
é·ã颿°ã®å®è¡ãäžæããæ¹æ³ãç¹ã«ãã®é¢æ°ã§å®è¡ã®ã¹ã¬ãããæ¡ä»¶å€æ°ãŸãã¯OSã®ããããã³ã°åŒã³åºãã§ãã¹ãªãŒããã§ããå Žåã¯ã©ãããã°ããã§ããïŒ
ãã®åé¡ã®ç¹æ®ãªã±ãŒã¹ã¯ãå®è¡ã¹ã¬ããå
šäœã®äžæã§ãã å®è¡ã¹ã¬ããã«å²ã蟌ãããã®3ã€ã®æ¢åã®ã¡ãœãããèŠãŠã¿ãŸãããïŒ pthread_cancel
ã boost::thread::interrupt
ããã³booleanãã©ã°ã
æ¢åã®ãœãªã¥ãŒã·ã§ã³
éžæããã¹ã¬ããã«å²ã蟌ã¿èŠæ±ãéä¿¡ããŸãã POSIX仿§ã«ã¯ãå²ã蟌ã¿å¯èœãªé¢æ°ã®ç¹å¥ãªãªã¹ã ïŒ read
ã write
ãªã©ïŒãå«ãŸããŠããŸãã ããã€ãã®ã¹ã¬ããã«å¯ŸããŠpthread_cancel
ãåŒã³åºããåŸããã®ã¹ã¬ããã®ãããã®é¢æ°ã¯ç¹å¥ãªã¿ã€ãã®äŸå€ãã¹ããŒãå§ããŸãã ãã®äŸå€ã¯ç¡èŠã§ããŸããããã®ãããªäŸå€ããã£ããããcatchãããã¯ã¯ããã«äŸå€ãã¹ããŒããå¿
èŠãããããããã®äŸå€ã¯ã¹ã¬ããã¹ã¿ãã¯ãå®å
šã«å·»ãæ»ããŠçµäºããŸãã ã¹ã¬ããã¯ã pthread_setcancelstate
颿°ã䜿çšããŠãåŒã³åºãã®äžæãäžæçã«é²ãããšãã§ããŸãïŒå¯èœãªäœ¿çšæ³ã®1ã€ã¯ããã¹ãã©ã¯ã¿ããã®ã³ã°é¢æ°ãªã©ããã®äŸå€ãåé¿ããããã§ãïŒã
é·æïŒ
- æ¡ä»¶å€æ°ã®åŸ
æ©ãäžæ¢ã§ããŸã
- OSããããã³ã°åŒã³åºããäžæã§ããŸã
- å²ã蟌ã¿èŠæ±ãç¡èŠããã®ãé£ãã
çæïŒ
- 倧ããªç§»æ€æ§ã®åé¡ïŒ Windowsã§ã®
pthread_cancel
ã®æãããªæ¬ åŠã«å ããŠãäžéšã®libcå®è£
ïŒ Androidã§äœ¿çšãããbionicãªã©ïŒã§ãæ¬ èœããŠããŸã std::condition_variable::wait
C ++ 14以éã®æšæºã§std::condition_variable::wait
ããstd::condition_variable::wait
åé¡- å²ã蟌ã¿å¯èœãªé¢æ°ã䜿çšããCã³ãŒãã§åé¡ãåŒãèµ·ããå¯èœæ§ããããŸãïŒç¹æ®å¹æã®ãªã¹ãïŒãªãœãŒã¹ãªãŒã¯ããã¥ãŒããã¯ã¹ãæééãã«ããã¯è§£é€ãããªããªã©ïŒã
- ãã¹ãã©ã¯ã¿ã®å²ã蟌ã¿é¢æ°ã«ã¯ç¹å¥ãªæ³šæãå¿
èŠã§ãïŒããšãã°ã
close
ã¯å²ã蟌ã¿é¢æ°ã§ãïŒ - äŸå€ã®ãªãç°å¢ã§ã¯äœ¿çšã§ããŸãã
- åã
ã®æ©èœãŸãã¯ã¿ã¹ã¯ãäžæããããã«äœ¿çšããããšã¯ã§ããŸããã
std::condition_variable::wait
åé¡ã¯ãC ++ 14 std::condition_variable::wait
ã«noexcept
仿§ãæå®ãããŠããããã«noexcept
ãŸãã pthread_setcancelstate
ã§å²ã蟌ã¿ãæå¹ã«ãããšãæ¡ä»¶å€æ°ã®åŸ
æ©ãäžæããæ©èœã倱ãããŸããå²ã蟌ã¿ãèš±å¯ããããšããã®ç¹å®ã®äŸå€ãã飲ã¿èŸŒããããšãã§ããªãããã noexcept
仿§ãæºããããšãã§ããŸããã
Boost.Threadã©ã€ãã©ãªã¯ã pthread_cancel
ã«ãããã䌌ããªãã·ã§ã³ã®ã¹ã¬ããå²ã蟌ã¿ã¡ã«ããºã ãæäŸããŸãã å®è¡ã®ãããŒãäžæããã«ã¯ã察å¿ããboost::thread
ãªããžã§ã¯ãã§interrupt
ã¡ãœãããåŒã³åºãã ãã§ååã§ãã boost::this_thread::interruption_point
颿°ã䜿çšããŠãçŸåšã®ã¹ã¬ããã®ã¹ããŒã¿ã¹ã確èªã§ããŸããå²ã蟌ã¿ã¹ã¬ããã§ã¯ããã®é¢æ°ã¯ã¿ã€ãboost::thread_interrupted
äŸå€ãã¹ããŒããŸãã BOOST_NO_EXCEPTIONSã䜿çšããŠäŸå€ã®äœ¿çšãçŠæ¢ãããŠããå Žåã boost::this_thread::interruption_requested
ã䜿çšããŠã¹ããŒã¿ã¹ã確èªã§ããŸãã Boost.Threadã§ã¯ã boost::condition_variable::wait
åŸ
æ©ãäžæããããšãã§ããŸãã ãããå®è£
ããã«ã¯ãã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžãšæ¡ä»¶å€æ°å
ã®è¿œå ã®ãã¥ãŒããã¯ã¹ã䜿çšããŸãã
é·æïŒ
- ç§»æ€æ§
boost::condition_variable::wait
ãäžæ¢ã§ããŸãboost::condition_variable::wait
- äŸå€ãªãç°å¢ã§äœ¿çšã§ããŸãã
çæïŒ
- Boost.Threadãžã®ãã€ã³ã-ãã®å²ã蟌ã¿ã¡ã«ããºã ã¯ãæšæºã®æ¡ä»¶å€æ°ãŸãã¯ã¹ã¬ããã§ã¯äœ¿çšã§ããŸãã
condition_variable
å
ã«è¿œå ã®mutexãå¿
èŠcondition_variable
- ãªãŒããŒãããïŒå
condition_variable::wait
2ã€ã®äœåãªããã¯/ããã¯è§£é€ãã¥ãŒããã¯ã¹ã远å ãcondition_variable::wait
- OSãããã¯ã³ãŒã«ãäžæã§ããŸãã
- åã
ã®æ©èœãŸãã¯ã¿ã¹ã¯ãäžæããããã«äœ¿çšããã®ã¯åé¡ã§ãïŒã³ãŒãã§å€æãããšãããã¯äŸå€ã䜿çšããŠã®ã¿å®è¡ã§ããŸãïŒ
- äŸå€ã®å²åŠã«å¯Ÿãã軜埮ãªéå-ãããŒã®äžæã¯ãããã°ã©ã ã®ã©ã€ããµã€ã¯ã«ã«ãããŠäŸå€çãªç¶æ³ã§ã¯ãããŸãã
ããŒã«ãã©ã°
StackOverflowã§pthread_cancel
ïŒ 1ã2ã3ã4 ïŒã«é¢ãã質åãèªãã å Žåãæãäžè¬çãªåçã®1ã€ã¯ã pthread_cancel
代ããã«ããŒã«ãã©ã°ã䜿çšãããã§ãã
äŸå€ã®ãããã®äŸã§alive
ã¢ãããã¯å€æ°ã¯ãããŒã«ãã©ã°ã§ãã
void use_thread() { std::atomic<bool> alive{true}; thread_wrapper t([&alive] { while(alive) do_something(); }); do_another_thing();
é·æïŒ
- ãã©ãããã©ãŒã ã«äŸåããªã
- ã¹ããªãŒã ã®ãã¬ãŒã¯ãã€ã³ãã¯æããã§ã
çæïŒ
- ã³ãŒãã®è€è£œ
- åè§£ãéªéã§ã-ãããã¯é¢æ°ãæžãç°¡åã§å¹ççãªæ¹æ³ã¯ãããŸãã
- æ¡ä»¶ä»ã倿°ã®åŸ
æ©ãäžæããªãã§ãã ããïŒç¹ã«ãããŒã«åãã©ã°ã䜿çšããŠã¯ã©ã¹ã®å€ã«ããå ŽåïŒ
- OSãããã¯ã³ãŒã«ãäžæã§ããŸãã
ãã£ã³ã»ã«ããŒã¯ã³
ã©ããã ããŒã«ãã©ã°ãåºã«ããŠãããã«é¢é£ããåé¡ã®è§£æ±ºãå§ããŸãããã ã³ãŒãã®éè€ïŒ ãã°ããã-ããŒã«ãã©ã°ãå¥ã®ã¯ã©ã¹ã«ã©ããããŸãããã ãããcancellation_token
ãšåŒã³ãŸãããã
class cancellation_token { public: explicit operator bool() const { return !_cancelled; } void cancel() { _cancelled = true; } private: std::atomic<bool> _cancelled; };
thread_wrapper
ã§ããŸãã
class thread_wrapper { public:
ããŠãããŒã¯ã³ãžã®ãªã³ã¯ãå¥ã®ã¹ã¬ããã§å®è¡ããã颿°ã«è»¢éããã ãã§ãïŒ
template<class Function, class... Args> thread_wrapper(Function&& f, Args&&... args) { _impl = std::thread(f, args..., std::ref(_token)); }
説æã®ããã«thread_wrapper
ãæžããŠããã®ã§ããŸã std::forward
ã䜿çšããããšã¯ã§ãããåæã«ãç§»åã³ã³ã¹ãã©ã¯ã¿ãŒãšswap
颿°ã§çºçããåé¡ãç¡èŠã§ããŸãã
use_thread
ãšäŸå€ãuse_thread
ãäŸãæãåºããŠuse_thread
ã
void use_thread() { std::atomic<bool> alive{true}; thread_wrapper t([&alive] { while(alive) do_something(); }); do_another_thing(); alive = false; }
cancel_tokenã®ãµããŒãã远å ããã«ã¯ãã©ã ãã«æ£ããåŒæ°ã远å ãalive
ãåé€ããã ãã§ãã
void use_thread() { thread_wrapper t([] (cancellation_token& token) { while(token) do_something(); }); do_another_thing(); }
ãããïŒ do_another_thing
ããäŸå€ãdo_another_thing
ããå Žåã§ãdo_another_thing
ãã¹ãã©ã¯ã¿thread_wrapper
ãŸã do_another_thing
cancellation_token::cancel
ãåŒã³åºããã¹ã¬ããã¯å®è¡ãå®äºããŸãã ããã«ãcancel_tokenã®ããŒã«ãã©ã°ã®ã³ãŒããåé€ãããšããã®äŸã§ã¯ã³ãŒãã®éã倧å¹
ã«åæžãããŸããã
åŸ
æ©ã®äžæ
æ¡ä»¶ä»ã倿°ã§åŸ
æ©ãããªã©ãããããã³ã°ã³ãŒã«ãäžæããããã«ããŒã¯ã³ãæãããšãã§ãã ç¹å®ã®å²ã蟌ã¿ã¡ã«ããºã ããæœè±¡åããã«ã¯ã cancellation_handler
ã€ã³ã¿ãŒãã§ã€ã¹ãå¿
èŠã§ãã
struct cancellation_handler { virtual void cancel() = 0; };
æ¡ä»¶å€æ°ã®åŸ
æ©ãäžæ¢ãããã³ãã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã
class cv_handler : public cancellation_handler { public: cv_handler(std::condition_variable& condition, std::unique_lock<mutex>& lock) : _condition(condition), _lock(lock) { } virtual void cancel() { unique_lock l(_lock.get_mutex()); _condition.notify_all(); } private: std::condition_variable& _condition; std::unique_lock<mutex>& _lock; };
ããã§ãcancelation_tokenã«cancel_handlerãžã®ãã€ã³ã¿ãŒã眮ããcancelation_handler cancellation_handler::cancel
ããcancellation_handler::cancel
ãåŒã³åºããŸãã
class cancellation_token { std::mutex _mutex; std::atomic<bool> _cancelled; cancellation_handler* _handler; public: explicit operator bool() const { return !_cancelled; } void cancel() { std::unique_lock<mutex> l(_mutex); if (_handler) _handler->cancel(); _cancelled = true; } void set_handler(cancellation_handler* handler) { std::unique_lock<mutex> l(_mutex); _handler = handler; } };
æ¡ä»¶å€æ°ã®åŸ
æ©ã®äžæããŒãžã§ã³ã¯ã次ã®ããã«ãªããŸãã
void cancellable_wait(std::condition_variable& cv, std::unique_lock<mutex>& l, cancellation_token& t) { cv_handler handler(cv, l);
泚æïŒ æå®ãããå®è£
ã¯ãäŸå€ãšã¹ã¬ããã»ãŒãã®äž¡æ¹ã®èгç¹ããå®å
šã§ã¯ãããŸããã 圌女ã¯ããã§ãanceration_handlerã®åäœã¡ã«ããºã ã説æããããã«ã®ã¿ããã«ããŸãã æ£ããå®è£
ãžã®ãªã³ã¯ã¯ãèšäºã®æåŸã«ãããŸãã
察å¿ããcancellation_handler
å®è£
ããããšã«ãããOSãžã®ããããã³ã°åŒã³åºããšä»ã®ã©ã€ãã©ãªããã®ããããã³ã°é¢æ°ãäžæããããã«ããŒã¯ã³ã«æããããšãã§ããŸãïŒãããã®é¢æ°ãåŸ
æ©ãäžæããã¡ã«ããºã ãå°ãªããšãæã£ãŠããå ŽåïŒã
åã¹ã¬ããã©ã€ãã©ãª
説æãããŠããããŒã¯ã³ããã³ãã©ãŒãããã³ã¹ã¬ããã¯ããªãŒãã³ãœãŒã¹ã©ã€ãã©ãªãšããŠå®è£
ãããŠããŸãïŒ https : //github.com/bo-on-software/rethread ã ããã¥ã¡ã³ã ïŒè±èªïŒã ãã¹ããããã³ãã³ãããŒã¯ ã
以äžã¯ãã³ãŒããšã©ã€ãã©ãªã«å®è£
ãããŠãããã®ãšã®äž»ãªéãã®ãªã¹ãã§ãã
cancellation_token
ã¯ãããã€ãã®å®è£
ãæã€ã€ã³ã¿ãŒãã§ãŒã¹ã§ãã äžæããã颿°ã¯ã 宿°ãªã³ã¯ã«ãã£ãŠcancelal_tokenãåãåããŸã- ããŒã¯ã³ã¯äžè¬çã«äœ¿çšãããæäœã«ãã¥ãŒããã¯ã¹ã®ä»£ããã«ã¢ãããã¯ã䜿çšããŸã
- ã¹ã¬ããã®ã©ãããŒã¯
rethread::thread
ãšåŒã°ãrethread::thread
ã©ã€ãã©ãªã«ãããã®ïŒ
- ããŒã¯ã³
- RAIIäºæã¹ããªãŒã
std::condition_variable
äºææ§ã®ããæ¡ä»¶å€æ°ã§ã®å²ã蟌ã¿å¯èœãªåŸ
æ©std::condition_variable
poll
åŸ
æ©ã®äžæ-ããã«ãããå€ãã®ããããã³ã°POSIXåŒã³åºãïŒ read
ã write
ãªã©ïŒã®äžæããŒãžã§ã³ãå®è£
ã§ããŸãã
æ§èœ
枬å®ã¯ãIntel Core i7-3630QM @ 2.4GHzããã»ããµãæèŒããã©ãããããã§å®è¡ãããŸããã
以äžã¯ãårethread
ããŒã¯ã³ãã³ãããŒã¯ã®çµæã§ãã
æ¬¡ã®æäœã®ããã©ãŒãã³ã¹ã枬å®ãããŸããã
- ç¶æ
ã®ç¢ºèªã¯ã
cancellation_token::is_cancelled()
颿°ïŒãŸãã¯åçã®ããŒã«åãžã®ã³ã³ããã¹ã倿cancellation_token::is_cancelled()
ãåŒã³åºãããšã®ä»£åã§ã - äžæããã颿°ã®åŒã³åºãã¯ãäžæãããããããã³ã°é¢æ°ã®ãªãŒããŒãããã§ããåŒã³åºãã®åã«ããŒã¯ã³ã«ãã³ãã©ãŒãç»é²ããåŒã³åºãã®çµäºåŸã«ãç»é²è§£é€ãããŸã
standalone_cancellation_token
1ã€äœæããŸã
Ubuntu 16.04
| CPUæéãns |
---|
ããŒã¯ã³ã¹ããŒã¿ã¹ã®ç¢ºèª | 1.7 |
å²ãèŸŒã¿æ©èœãåŒã³åºã | 15.0 |
ããŒã¯ã³äœæ | 21.3 |
Windows 10
| CPUæéãns |
---|
ããŒã¯ã³ã¹ããŒã¿ã¹ã®ç¢ºèª | 2.8 |
å²ãèŸŒã¿æ©èœãåŒã³åºã | 17.0 |
ããŒã¯ã³äœæ | 33.0 |
ãã€ãã¹ã®ãªãŒããŒããã
ãã®ãããªäœãå²ã蟌ã¿ãªãŒããŒãããã¯ãè峿·±ã广ãçã¿åºããŸãã
ç¶æ³ã«ãã£ãŠã¯ãå²ã蟌ã¿é¢æ°ã¯ãéåžžã®ãã¢ãããŒããããé«éã§ãã
ããŒã¯ã³ã䜿çšããªãã³ãŒãã§ã¯ããããã¯æ©èœãæ°žä¹
ã«ãããã¯ããããšã¯ã§ããŸãã-ãã®åŸããæ£åžžãªãã¢ããªã±ãŒã·ã§ã³ã®çµäºãéæããããšã¯ã§ããŸããexit(1);
ãããªç°åžžãæ£åžžãšèŠãªãããšã¯ã§ããŸããïŒã æ°žç¶çãªãããã¯ãåé¿ããã¹ããŒã¿ã¹ã宿çã«ç¢ºèªããã«ã¯ãã¿ã€ã ã¢ãŠããå¿
èŠã§ãã ããšãã°ãããïŒ
while (alive) { _condition.wait_for(lock, std::chrono::milliseconds(100));
ãŸãããã®ãããªã³ãŒãã¯ããã©ã°ã確èªããããã«100ããªç§ããšã«èµ·åããŸãïŒã¿ã€ã ã¢ãŠãå€ã¯å¢ããããšãã§ããŸããããåççãªãã¢ããªã±ãŒã·ã§ã³çµäºæéã«ãã£ãŠäžããå¶éãããŸãïŒã
第äºã«ããã®ã³ãŒãã¯ãã®ãããªç¡æå³ãªèŠéããªããŠãæé©ã§ã¯ãããŸããã äºå®ã¯ã condition_variable::wait_for(...)
ã®åŒã³åºãã¯condition_variable::wait_for(...)
ãããå¹çãcondition_variable::wait(...)
å°ãªããšããçŸåšã®æå»ãååŸãããŠã§ã€ã¯ã¢ããæéãèšç®ããå¿
èŠããããŸãã
ãã®ã¹ããŒãã¡ã³ãã蚌æããããã«ãrethread_testingã§2ã€ã®åæãã³ãããŒã¯ãäœæãããã«ãã¹ã¬ãããã¥ãŒã®2ã€ã®åºæ¬çãªå®è£
ãæ¯èŒããŸããããéåžžãïŒã¿ã€ã ã¢ãŠãä»ãïŒãšå²ã蟌ã¿ïŒããŒã¯ã³ä»ãïŒã§ãã ããã»ããµæéã¯ããã¥ãŒå
ã®1ã€ã®ãªããžã§ã¯ãã®åºçŸãåŸ
ã€ããã«æž¬å®ãããŸããã
| CPUæéãns |
---|
Ubuntu 16.04ïŒG ++ 5.3.1ïŒãéåžžã®ããã¥ãŒïŒ | 5913 |
Ubuntu 16.04ïŒG ++ 5.3.1ïŒäžæããããã¥ãŒïŒ | 5824 |
Windows 10ããã³MSVS 2015ïŒéåžžã®ãã¥ãŒïŒ | 2467 |
Windows 10ããã³MSVS 2015ïŒå²ã蟌ã¿ãã¥ãŒïŒ | 1729 |
ãã®ãããMSVS 2015ã§ã¯ãå²ã蟌ã¿å¯èœãªããŒãžã§ã³ã¯ã¿ã€ã ã¢ãŠãã®ãããéåžžã®ãããŒãžã§ã³ããã1.4éãå®è¡ãããŸãã Ubuntu 16.04ã§ã¯ãéãã¯ããã»ã©é¡èã§ã¯ãããŸããããäžæãããããŒãžã§ã³ã¯æããã«ãéåžžã®ãããŒãžã§ã³ãããåªããŠããŸãã
ãããã«
ãããåé¡ã®å¯äžã®å¯èœãªè§£æ±ºçã§ã¯ãããŸããã æãé
åçãªä»£æ¿æ¹æ³ã¯ãããŒã¯ã³ãã¹ã¬ããããŒã«ã«ã¹ãã¬ãŒãžã«é
眮ããäžææã«äŸå€ãã¹ããŒããããšã§ãã åäœã¯boost::thread::interrupt
ã«äŒŒãŠãboost::thread::interrupt
ãã忡件倿°ã«è¿œå ã®mutexããªãããªãŒããŒãããã倧å¹
ã«å°ãªããªããŸãã ãã®ã¢ãããŒãã®äž»ãªæ¬ ç¹ã¯ãæ¢ã«è¿°ã¹ãäŸå€ã®å²åŠã®éåãšãã¬ãŒã¯ãã€ã³ãã®éèªææ§ã§ãã
ããŒã¯ã³ã䜿çšããã¢ãããŒãã®éèŠãªå©ç¹ã¯ããããŒå
šäœã§ã¯ãªããåå¥ã®ã¿ã¹ã¯ãäžæã§ããããšã§ããã©ã€ãã©ãªã«å®è£
ãããŠããcancellation_token_source
ã©ã€ãã©ãªã䜿çšãããšãåæã«è€æ°ã®ã¿ã¹ã¯ãäžæã§ããŸãã
ã»ãšãã©ãã¹ãŠã®ãŠã£ãã·ã¥ãªã¹ããã©ã€ãã©ãªã«å®è£
ããŸããã ç§ã®æèŠã§ã¯ããã¡ã€ã«ããœã±ãããæäœãããããªãããã¯ã·ã¹ãã ã³ãŒã«ãšã®çµ±åãäžè¶³ããŠããŸãã read
ã write
ã connect
ã accept
ãªã©ã®å²ã蟌ã¿å¯èœãªããŒãžã§ã³ãæžã蟌ã¿ãŸãã é£ããããšã§ã¯ãããŸãããäž»ãªåé¡ã¯ãããŒã¯ã³ãæšæºã®iostreamã«è²Œãä»ãããããªãããšãšãäžè¬ã«åãå
¥ããããŠããä»£æ¿ææ®µããªãããšã§ãã