ããã«ã¡ã¯ãHabrïŒ Deb Haldarã®èšäº
ãTop 20 C ++ multithreading errors andããããåé¿ããæ¹æ³ãã®ç¿»èš³ã«æ³šç®ããŠãã ããã
æ ç»ãThe Loop of Timeãã®ã·ãŒã³ïŒ2012ïŒãã«ãã¹ã¬ããã¯ãããã°ã©ãã³ã°ãç¹ã«C ++ã§æãé£ããåéã®1ã€ã§ãã éçºã®é·å¹Žã«ããã£ãŠãç§ã¯å€ãã®ãã¹ãç¯ããŸããã 幞ããªããšã«ããããã®ã»ãšãã©ã¯ã¬ãã¥ãŒã³ãŒããšãã¹ãã«ãã£ãŠç¹å®ãããŸããã ãããããªãããã®æ¹æ³ã§çç£æ§ãäœäžãããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ãç·šéããå¿
èŠããããŸãããããã¯åžžã«é«äŸ¡ã§ãã
ãã®èšäºã§ã¯ãç¥ã£ãŠãããã¹ãŠã®ãšã©ãŒãå¯èœãªè§£æ±ºçã§åé¡ããããšããŸããã ä»ã®èœãšãç©Žã«æ°ä»ããŠããå ŽåããŸãã¯èª¬æãããŠãããšã©ãŒã解決ããããã®ææ¡ãããå Žåã¯ãèšäºã®äžã«ã³ã¡ã³ããæ®ããŠãã ããã
ééãïŒ1ïŒã¢ããªã±ãŒã·ã§ã³ãçµäºããåã«joinïŒïŒã䜿çšããŠããã¯ã°ã©ãŠã³ãã¹ã¬ãããåŸ
æ©ããªã
ããã°ã©ã ãçµäºããåã«ã¹ããªãŒã ã®ã¢ã¿ããïŒ
joinïŒïŒ ïŒãŸãã¯
ãã¿ãã ïŒ
detachïŒïŒ ïŒïŒ
ãžã§ã€ã³ã§ããªãããã«ããïŒãå¿ãããšãã¯ã©ãã·ã¥ã«ã€ãªãããŸãã ïŒç¿»èš³ã«ã¯ã
joinïŒïŒã®ã³ã³ããã¹ãã§
joinãšããåèªãå«ãŸãã
detachïŒïŒã®ã³ã³ããã¹ãã§
detachãå«ãŸããŸãããããã¯å®å
šã«æ£ããããã§ã¯ãããŸãããå®éã
joinïŒïŒã¯ãå®è¡ã®ã¹ã¬ãããå¥ã®ã¹ã¬ããã®å®äºãåŸ
æ©ããæ¥ç¶ãŸãã¯ã¹ã¬ããã®ããŒãžãçºçããªããã€ã³ãã§ã[ã³ã¡ã³ã翻蚳è
]ïŒã
以äžã®äŸã§ã¯ãã¡ã€ã³ã¹ã¬ãã
ã§ã¹ã¬ããt1ã®
joinïŒïŒãå®è¡
ããã®ãå¿ããŠããŸããã
#include "stdafx.h"
#include <iostream>
#include <thread>
using namespace std ;
void LaunchRocket ( )
{
cout << "Launching Rocket" << endl ;
}
int main ( )
{
thread t1 ( LaunchRocket ) ;
//t1.join(); // join-
return 0 ;
}
ãªãããã°ã©ã ãã¯ã©ãã·ã¥ããã®ã§ããïŒïŒ
mainïŒïŒé¢æ°ã®æåŸã§ã倿°t1ãã¹ã³ãŒãå€ã«ãªããã¹ã¬ãããã¹ãã©ã¯ã¿ãåŒã³åºãããããã§ãã ãã¹ãã©ã¯ã¿ã¯ãã¹ã¬ããt1ãåå
å¯èœãã©ããããã§ãã¯ããŸãã ã¹ã¬ããã¯ãåãé¢ãããŠããªããã°åå
å¯èœã§ãã ãã®å Žåã
std :: terminateã¯ãã¹ãã©ã¯ã¿ã§åŒã³åºãããŸãã ããšãã°ãMSVC ++ã³ã³ãã€ã©ã®æ©èœã¯æ¬¡ã®ãšããã§ãã
~thread ( ) _NOEXCEPT
{ // clean up
if ( joinable ( ) )
XSTD terminate ( ) ;
}
ã¿ã¹ã¯ã«å¿ããŠãåé¡ãä¿®æ£ãã2ã€ã®æ¹æ³ããããŸãã
1.ã¡ã€ã³ã¹ã¬ãã
ã§ã¹ã¬ããt1ã®
joinïŒïŒãåŒã³åºããŸãã
int main ( )
{
thread t1 ( LaunchRocket ) ;
t1. join ( ) ; // join t1,
return 0 ;
}
2.ã¡ã€ã³ã¹ããªãŒã ããã¹ããªãŒã t1ãåãé¢ãããæªéåããããã¹ããªãŒã ãšããŠåäœãç¶ããããã«ããŸãã
int main ( )
{
thread t1 ( LaunchRocket ) ;
t1. detach ( ) ; // t1
return 0 ;
}
ééã2ïŒä»¥åã«åãé¢ãããã¹ã¬ãããæ¥ç¶ããããšãã
ããã°ã©ã ã®åäœäžã«
ãã¿ããã¹ããªãŒã ãããå Žåãã¡ã€ã³ã¹ããªãŒã ã«ã¢ã¿ããããããšã¯ã§ããŸããã ããã¯éåžžã«æãããªééãã§ãã åé¡ã¯ãã¹ããªãŒã ã®åºå®ãè§£é€ããŠãããæ°çŸè¡ã®ã³ãŒããèšè¿°ããŠåã¢ã¿ããã§ããããšã§ãã çµå±ã300è¡ãæžãæ»ããããšãèŠããŠãã人ã¯ããŸããïŒ
åé¡ã¯ãããã«ããã³ã³ãã€ã«ãšã©ãŒãçºçããã代ããã«ããã°ã©ã ãèµ·åæã«ã¯ã©ãã·ã¥ããããšã§ãã äŸïŒ
#include "stdafx.h"
#include <iostream>
#include <thread>
using namespace std ;
void LaunchRocket ( )
{
cout << "Launching Rocket" << endl ;
}
int main ( )
{
thread t1 ( LaunchRocket ) ;
t1. detach ( ) ;
//..... 100 -
t1. join ( ) ; // CRASH !!!
return 0 ;
}
解決çã¯ãã¹ã¬ãããåŒã³åºãã¹ã¬ããã«ã¢ã¿ããããåã«ãåžžã«ã¹ã¬ããã®
joinableïŒïŒããã§ãã¯ããããšã§ãã
int main ( )
{
thread t1 ( LaunchRocket ) ;
t1. detach ( ) ;
//..... 100 -
if ( t1. joinable ( ) )
{
t1. join ( ) ;
}
return 0 ;
}
ééãïŒ3ïŒstd :: thread :: joinïŒïŒã¯å®è¡ã®åŒã³åºãã¹ã¬ããããããã¯ãããšãã誀解
å®éã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãå€ãã®å Žåããããã¯ãŒã¯I / Oã®åŠçããŠãŒã¶ãŒããã¿ã³ãã¯ãªãã¯ããã®ãåŸ
ã€ãªã©ã®ãé·æéã«ããããæäœãåé¢ããå¿
èŠããããŸãã ãã®ãããªã¯ãŒã¯ãããŒïŒUIã¬ã³ããªã³ã°ã¹ã¬ãããªã©
ïŒã®joinïŒïŒãåŒã³åºããšããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããã³ã°ããå ŽåããããŸãã ããé©åãªå®è£
æ¹æ³ããããŸãã
ããšãã°ãGUIã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã¯ãŒã«ãŒã¹ã¬ãããå®äºãããšãUIã¹ã¬ããã«ã¡ãã»ãŒãžãéä¿¡ã§ããŸãã UIã¹ããªãŒã ã«ã¯ãããŠã¹ã®ç§»åãããŒã®æŒäžãªã©ã®ç¬èªã®ã€ãã³ãåŠçã«ãŒãããããŸãã ãã®ã«ãŒãã¯ãã¯ãŒã«ãŒã¹ã¬ããããã¡ãã»ãŒãžãåä¿¡ããããããã³ã°
joinïŒïŒã¡ãœãããåŒã³åºãããšãªãã¡ãã»ãŒãžã«å¿çããããšãã§ããŸãã
ãã®ãŸãã«çç±ã§ãMicrosoftã®
WinRTãã©ãããã©ãŒã ã§ã®ã»ãšãã©ãã¹ãŠã®ãŠãŒã¶ãŒã€ã³ã¿ã©ã¯ã·ã§ã³ã¯éåæã«ãªããåæã®ä»£æ¿ã¯å©çšã§ããŸããã ãããã®æ±ºå®ã¯ãéçºè
ãå¯èœãªéãæé«ã®ãšã³ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããAPIã䜿çšããããã«ããããã«è¡ãããŸããã ãã®ãããã¯ã®è©³çްã«ã€ããŠã¯ãã
Modern C ++ and Windows Store Apps ãããã¥ã¢ã«ãåç
§ããŠãã ããã
ééã4ïŒã¹ããªãŒã 颿°ã®åŒæ°ãããã©ã«ãã§åç
§ã«ãã£ãŠæž¡ããããšä»®å®ãã
ã¹ããªãŒã 颿°ãžã®åŒæ°ã¯ããã©ã«ãã§å€ã§æž¡ãããŸãã æž¡ãããåŒæ°ã«å€æŽãå ããå¿
èŠãããå Žåã¯ã
std :: refïŒïŒé¢æ°ã䜿çšããŠåç
§ã§æž¡ãå¿
èŠããããŸãã
ãã¿ãã¬ã®äžã§ã
QïŒA-ã¹ã¬ãã管çã®åºæ¬ïŒDeb HaldarïŒãä»ããå¥ã®
C ++ 11ãã«ãã¹ã¬ãããã¥ãŒããªã¢ã«ã®äŸã¯ããã©ã¡ãŒã¿ãŒã®åãæž¡ãã瀺ããŠããŸã[çŽã 翻蚳è
]ã
詳现ïŒã³ãŒããå®è¡ãããšãïŒ
#include "stdafx.h"
#include <string>
#include <thread>
#include <iostream>
#include <functional>
using namespace std ;
void ChangeCurrentMissileTarget ( string & targetCity )
{
targetCity = "Metropolis" ;
cout << " Changing The Target City To " << targetCity << endl ;
}
int main ( )
{
string targetCity = "Star City" ;
thread t1 ( ChangeCurrentMissileTarget, targetCity ) ;
t1. join ( ) ;
cout << "Current Target City is " << targetCity << endl ;
return 0 ;
}
ã¿ãŒããã«ã«è¡šç€ºãããŸãïŒ
Changing The Target City To Metropolis
Current Target City is Star City
ã芧ã®ãšãããåç
§ã«ãã£ãŠã¹ããªãŒã ã§åŒã³åºããã颿°ãåãåãtargetCity倿°ã®å€ã¯å€æŽãããŠããŸããã
åŒæ°ãæž¡ãã«ã¯ã std :: refïŒïŒã䜿çšããŠã³ãŒããæžãæããŸãã
#include "stdafx.h"
#include <string>
#include <thread>
#include <iostream>
#include <functional>
using namespace std ;
void ChangeCurrentMissileTarget ( string & targetCity )
{
targetCity = "Metropolis" ;
cout << " Changing The Target City To " << targetCity << endl ;
}
int main ( )
{
string targetCity = "Star City" ;
thread t1 ( ChangeCurrentMissileTarget, std :: ref ( targetCity ) ) ;
t1. join ( ) ;
cout << "Current Target City is " << targetCity << endl ;
return 0 ;
}
åºåãããŸãïŒ
Changing The Target City To Metropolis
Current Target City is Metropolis
æ°ããã¹ã¬ããã§è¡ããã倿Žã¯ã main颿°ã§å®£èšããã³åæåãããtargetCity倿°ã®å€ã«åœ±é¿ããŸãã
ééã5ïŒã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ïŒãã¥ãŒããã¯ã¹ãªã©ïŒã䜿çšããŠå
±æããŒã¿ãšãªãœãŒã¹ãä¿è·ããªã
ãã«ãã¹ã¬ããç°å¢ã§ã¯ãéåžžãè€æ°ã®ã¹ã¬ããããªãœãŒã¹ãšå
±æããŒã¿ã奪ãåããŸãã å€ãã®å ŽåããªãœãŒã¹ãšããŒã¿ãžã®ã¢ã¯ã»ã¹ãäžç¢ºå®ãªç¶æ
ã«ãªããŸãããã ãããããã®ã¢ã¯ã»ã¹ã¯ããã€ã§ã1ã€ã®å®è¡ã¹ã¬ããã®ã¿ããããã®æäœãå®è¡ã§ããã¡ã«ããºã ã«ãã£ãŠä¿è·ãããŠããå Žåãé€ããŸãã
以äžã®äŸã§ã¯ã
std :: coutã¯6ã€ã®ã¹ã¬ãããåäœããå
±æãªãœãŒã¹ã§ãïŒt1-t5 + mainïŒã
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
using namespace std ;
std :: mutex mu ;
void CallHome ( string message )
{
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
}
int main ( )
{
thread t1 ( CallHome, "Hello from Jupiter" ) ;
thread t2 ( CallHome, "Hello from Pluto" ) ;
thread t3 ( CallHome, "Hello from Moon" ) ;
CallHome ( "Hello from Main/Earth" ) ;
thread t4 ( CallHome, "Hello from Uranus" ) ;
thread t5 ( CallHome, "Hello from Neptune" ) ;
t1. join ( ) ;
t2. join ( ) ;
t3. join ( ) ;
t4. join ( ) ;
t5. join ( ) ;
return 0 ;
}
ãã®ããã°ã©ã ãå®è¡ãããšãçµè«ãåŸãããŸãã
Thread 0x1000fb5c0 says Hello from Main/Earth
Thread Thread Thread 0x700005bd20000x700005b4f000 says says Thread Thread Hello from Pluto0x700005c55000Hello from Jupiter says 0x700005d5b000Hello from Moon
0x700005cd8000 says says Hello from Uranus
Hello from Neptune
ããã¯ã5ã€ã®ã¹ã¬ãããã©ã³ãã ãªé åºã§åæã«åºåã¹ããªãŒã ã«ã¢ã¯ã»ã¹ããŠããããã§ãã çµè«ãããå
·äœçã«ããã«ã¯ã
std :: mutexã䜿çšããŠå
±æãªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãä¿è·ããå¿
èŠããããŸãã
CallHomeïŒïŒé¢æ°ã倿Žããã ãã§ã
std :: coutã䜿çšããåã«ãã¥ãŒããã¯ã¹ããã£ããã£ãããã®åŸè§£æŸããŸãã
void CallHome ( string message )
{
mu. lock ( ) ;
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
mu. unlock ( ) ;
}
ééã6ïŒã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ãçµäºããåŸã«ããã¯ãè§£é€ããã®ãå¿ãã
åã®ãã©ã°ã©ãã§ã¯ãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ããã¥ãŒããã¯ã¹ã§ä¿è·ããæ¹æ³ãèŠãŸããã ãã ããmutexã§
lockïŒïŒããã³
unlockïŒïŒã¡ãœãããçŽæ¥åŒã³åºãããšã¯ãä¿æãããããã¯ã®ä»äžãå¿ããå¯èœæ§ããããããæšå¥šããããªãã·ã§ã³ã§ã¯ãããŸããã æ¬¡ã«äœãèµ·ãããŸããïŒ ãªãœãŒã¹ã®è§£æŸãåŸ
æ©ããŠããä»ã®ãã¹ãŠã®ã¹ã¬ããã¯ç¡éã«ãããã¯ãããããã°ã©ã ããã³ã°ããå¯èœæ§ããããŸãã
åæäŸã§ã¯ã
CallHomeïŒïŒé¢æ°åŒã³åºãã§ãã¥ãŒããã¯ã¹ãããã¯è§£é€ããã®ãå¿ããå Žåãã¹ããªãŒã t1ããã®æåã®ã¡ãã»ãŒãžãæšæºã¹ããªãŒã ã«åºåãããããã°ã©ã ãã¯ã©ãã·ã¥ããŸãã ããã¯ãã¹ã¬ããt1ããã¥ãŒããã¯ã¹ããã¯ãåä¿¡ããæ®ãã®ã¹ã¬ããããã®ããã¯ãè§£é€ãããã®ãåŸ
ã€ããã§ãã
void CallHome ( string message )
{
mu. lock ( ) ;
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
//mu.unlock();
}
以äžã¯ãã®ã³ãŒãã®åºåã§ã-ããã°ã©ã ãã¯ã©ãã·ã¥ãã端æ«ã«å¯äžã®ã¡ãã»ãŒãžã衚瀺ãããçµäºããŸããã§ããïŒ
Thread 0x700005986000 says Hello from Pluto
ãã®ãããªãšã©ãŒã¯é »ç¹ã«çºçãããããmutexããçŽæ¥
lockïŒïŒ/ unlockïŒïŒã¡ãœããã䜿çšããããšã¯æãŸãããããŸããã 代ããã«ã
RADã€ãã£ãªã ã䜿çšããŠããã¯ã®æå¹æéãå¶åŸ¡ãã
std :: lock_guardãã³ãã¬ãŒãã¯ã©ã¹ã䜿çšããŸãã
lock_guardãªããžã§ã¯ããäœæããããšãmutexãåŒãç¶ãããšããŸãã ããã°ã©ã ã
lock_guardãªããžã§ã¯ãã®ã¹ã³ãŒããåºããšããã¹ãã©ã¯ã¿ãåŒã³åºããããã¥ãŒããã¯ã¹ãè§£æŸãããŸãã
std :: lock_guardãªããžã§ã¯ãã䜿çšããŠã
CallHomeïŒïŒé¢æ°ãæžãæããŸãã
void CallHome ( string message )
{
std :: lock_guard < std :: mutex > lock ( mu ) ; //
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
} // lock_guard
ééã7ïŒã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã®ãµã€ãºãå¿
èŠä»¥äžã«å€§ãããã
1ã€ã®ã¹ã¬ãããã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³å
ã§å®è¡ããããšããããå
¥åããããšããä»ã®ãã¹ãŠã®ã¹ã¬ããã¯åºæ¬çã«ãããã¯ãããŸãã ã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã«ã¯ã§ããã ãå°ãªãæç€ºãä¿æããå¿
èŠããããŸãã 説æã®ããã«ã倧ããªã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ãæã€äžæ£ãªã³ãŒãã®äŸã瀺ããŸãã
void CallHome ( string message )
{
std :: lock_guard < std :: mutex > lock ( mu ) ; // , std::cout
ReadFifyThousandRecords ( ) ;
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
} // lock_guard mu
ReadFifyThousandRecordsïŒïŒã¡ãœããã¯ããŒã¿ã倿ŽããŸããã ããã¯ãããç¶æ
ã§å®è¡ããçç±ã¯ãããŸããã ãã®ã¡ãœããã10ç§éå®è¡ãããããŒã¿ããŒã¹ãã5äžè¡ãèªã¿åããããšãä»ã®ãã¹ãŠã®ã¹ã¬ããããã®æéå
šäœã«ããã£ãŠäžå¿
èŠã«ãããã¯ãããŸãã ããã¯ãããã°ã©ã ã®ããã©ãŒãã³ã¹ã«æ·±å»ãªåœ±é¿ãäžããå¯èœæ§ããããŸãã
æ£ãã解決çã¯ãã¯ãªãã£ã«ã«ã»ã¯ã·ã§ã³ã§
std :: coutã®ã¿ã䜿çšãç¶ããããšã§ãã
void CallHome ( string message )
{
ReadFifyThousandRecords ( ) ; // ..
std :: lock_guard < std :: mutex > lock ( mu ) ; // , std::cout
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
} // lock_guard mu
ééã8ïŒè€æ°ã®ããã¯ãç°ãªãé åºã§ååŸãã
ããã¯ã
ãããããã¯ã®æãäžè¬çãªåå ã®1ã€ã§ãããä»ã®ã¹ã¬ããã«ãã£ãŠãããã¯ããããªãœãŒã¹ãžã®ã¢ã¯ã»ã¹ãåŸ
æ©ããŠããããã«ã¹ã¬ãããç¡éã«ãããã¯ãããç¶æ³ã§ãã äŸãèããŠã¿ãŸãããïŒ
ã¹ããªãŒã 1 | ã¹ããªãŒã 2 |
---|
ããã¯A | ããã¯B |
// ...äžéšã®æäœ | // ...äžéšã®æäœ |
ããã¯B | ããã¯A |
// ...ãã®ä»ã®æäœ | // ...ãã®ä»ã®æäœ |
Bã®ããã¯ãè§£é€ | Aã®ããã¯ãè§£é€ |
Aã®ããã¯ãè§£é€ | Bã®ããã¯ãè§£é€ |
ã¹ã¬ãã1ãBãããã¯ããããšããŠãã¹ã¬ãã2ããã§ã«Bãããã¯ããŠããããã«ãããã¯ãããç¶æ³ãçºçããå ŽåããããŸãã åæã«ã2çªç®ã®ã¹ã¬ããã¯ããã¯Aããã£ããã£ããããšããŠããŸãããæåã®ã¹ã¬ããã«ãã£ãŠãã£ããã£ããããããããã¯Aããã£ããã£ã§ããŸããã ã¹ã¬ãã1ã¯ãBãããã¯ãããŸã§ããã¯Aãè§£æŸã§ããŸããã ã€ãŸããããã°ã©ã ãããªãŒãºããŸãã
ãã®ã³ãŒãäŸã¯ã
ãããããã¯ã®åçŸã«åœ¹ç«ã¡ãŸãã
#include "stdafx.h"
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
using namespace std ;
std :: mutex muA ;
std :: mutex muB ;
void CallHome_Th1 ( string message )
{
muA. lock ( ) ;
// -
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 100 ) ) ;
muB. lock ( ) ;
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
muB. unlock ( ) ;
muA. unlock ( ) ;
}
void CallHome_Th2 ( string message )
{
muB. lock ( ) ;
// -
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 100 ) ) ;
muA. lock ( ) ;
cout << "Thread " << this_thread :: get_id ( ) << " says " << message << endl ;
muA. unlock ( ) ;
muB. unlock ( ) ;
}
int main ( )
{
thread t1 ( CallHome_Th1, "Hello from Jupiter" ) ;
thread t2 ( CallHome_Th2, "Hello from Pluto" ) ;
t1. join ( ) ;
t2. join ( ) ;
return 0 ;
}
ãã®ã³ãŒããå®è¡ãããšãã¯ã©ãã·ã¥ããŸãã ã¹ã¬ãããŠã£ã³ããŠã§ãããã¬ãããã«æ·±ãèŠããšãæåã®ã¹ã¬ããïŒ
CallHome_Th1ïŒïŒãã
åŒã³åºãããïŒãmutex Bããã¯ãååŸããããšããŠããã®ã«å¯Ÿããã¹ã¬ãã2ïŒ
CallHome_Th2ïŒïŒãã
åŒã³åºãããïŒã¯mutex Aããããã¯ããããšããŠããããšã
ããããŸããæåã§ããããããããã¯ãçºçããŸãïŒ

ïŒåçã¯ã¯ãªãã¯å¯èœã§ãïŒ
ããªãã¯ããã«ã€ããŠäœãã§ããŸããïŒ æè¯ã®è§£æ±ºçã¯ãããã¯ããã¯ãæ¯ååãé åºã§çºçããããã«ã³ãŒããåæ§ç¯ããããšã§ãã
ç¶æ³ã«å¿ããŠãä»ã®æŠç¥ã䜿çšã§ããŸãã
1.ã©ãããŒ
ã¯ã©ã¹std :: scoped_lockã䜿çšããŠãè€æ°ã®ããã¯ãå
±åã§ãã£ããã£ããŸãã
std :: scoped_lock lock { muA, muB } ;
2.ã¯ã©ã¹
std :: timed_mutexã䜿çšããŸãããã®ã¯ã©ã¹ã§ã¯ãã¿ã€ã ã¢ãŠããæå®ã§ããŸãããã®åŸããªãœãŒã¹ã䜿çšã§ããªããªã£ãå Žåã«ããã¯ãè§£é€ãããŸãã
std :: timed_mutex m ;
void DoSome ( ) {
std :: chrono :: milliseconds timeout ( 100 ) ;
while ( true ) {
if ( m. try_lock_for ( timeout ) ) {
std :: cout << std :: this_thread :: get_id ( ) << ": acquire mutex successfully" << std :: endl ;
m. unlock ( ) ;
} else {
std :: cout << std :: this_thread :: get_id ( ) << ": can't acquire mutex, do something else" << std :: endl ;
}
}
}
ééã9ïŒstdãäºéã«ãã£ããã£ããããšãã:: mutexããã¯
ããã¯ã2åããã¯ããããšãããšãæªå®çŸ©ã®åäœãçºçããŸãã ã»ãšãã©ã®ãããã°å®è£
ã§ã¯ãããã¯ã¯ã©ãã·ã¥ããŸãã ããšãã°ã次ã®ã³ãŒãã§ã¯ã
LaunchRocketïŒïŒã¯ mutex
ãããã¯ããŠãã
StartThrusterïŒïŒãåŒã³åºããŸãã äžæè°ãªããšã«ãäžèšã®ã³ãŒãã§ã¯ãããã°ã©ã ã®éåžžã®åäœäžã«ãã®åé¡ã¯çºçããŸãããåé¡ã¯äŸå€ãã¹ããŒããããšãã«ã®ã¿çºçããæªå®çŸ©ã®åäœãŸãã¯ããã°ã©ã ã®ç°åžžçµäºã䌎ããŸãã
#include "stdafx.h"
#include <iostream>
#include <thread>
#include <mutex>
std :: mutex mu ;
static int counter = 0 ;
void StartThruster ( )
{
try
{
// -
}
catch ( ... )
{
std :: lock_guard < std :: mutex > lock ( mu ) ;
std :: cout << "Launching rocket" << std :: endl ;
}
}
void LaunchRocket ( )
{
std :: lock_guard < std :: mutex > lock ( mu ) ;
counter ++ ;
StartThruster ( ) ;
}
int main ( )
{
std :: thread t1 ( LaunchRocket ) ;
t1. join ( ) ;
return 0 ;
}
ãã®åé¡ã解決ããã«ã¯ã以åã«åä¿¡ããããã¯ã®åååŸãé²ãããã«ã³ãŒããä¿®æ£ããå¿
èŠããããŸãã
std :: recursive_mutexãæŸèæã®ãœãªã¥ãŒã·ã§ã³ãšããŠäœ¿çšã§ããŸããããã®ãããªãœãªã¥ãŒã·ã§ã³ã¯ã»ãšãã©ã®å Žåãããã°ã©ã ã®ã¢ãŒããã¯ãã£ã貧匱ã§ããããšã瀺ããŠããŸãã
ééã10ïŒstd ::åååã§ååãªå Žåã«mutexã䜿çšãã
ããŒã«å€ãæŽæ°ã«ãŠã³ã¿ãŒãªã©ã®åçŽãªããŒã¿åã倿Žããå¿
èŠãããå Žåã
stdïŒatomicã䜿çšãããšãäžè¬ã«ãã¥ãŒããã¯ã¹ã䜿çšãããããããã©ãŒãã³ã¹ãåäžããŸãã
ããšãã°ãæ¬¡ã®æ§æã䜿çšãã代ããã«ïŒ
int counter ;
...
mu. lock ( ) ;
counter ++ ;
mu. unlock ( ) ;
倿°ã
std :: atomicãšããŠå®£èšããããšãã
å§ãããŸãã
std :: atomic < int > counter ;
...
counter ++ ;
ãã¥ãŒããã¯ã¹ãšã¢ãããã¯ã®è©³çŽ°ãªæ¯èŒã«ã€ããŠã¯ãèšäº
ãæ¯èŒïŒC ++ 11 vs. ãã¥ãŒããã¯ã¹ãšRWããã¯Â»ééã11ïŒç©ºãã¹ã¬ããã®ããŒã«ã䜿çšãã代ããã«ã倿°ã®ã¹ã¬ãããçŽæ¥äœæããã³ç Žæ£ãã
ã¹ã¬ããã®äœæãšç Žæ£ã¯ãããã»ããµæéã®èгç¹ãããããšé«äŸ¡ãªæäœã§ãã ã·ã¹ãã ãèšç®è² è·ã®é«ãæäœãããšãã°ã°ã©ãã£ãã¯ã¹ã®ã¬ã³ããªã³ã°ãã²ãŒã ç©çåŠã®èšç®ãå®è¡ããŠããéã«ã¹ããªãŒã ãäœæããããšããããšãæ³åããŠãã ããã ãã®ãããªã¿ã¹ã¯ã«ãã䜿çšãããã¢ãããŒãã¯ãããã»ã¹ã®ã©ã€ããµã€ã¯ã«å
šäœãéããŠãã£ã¹ã¯ãžã®æžã蟌ã¿ããããã¯ãŒã¯çµç±ã®ããŒã¿éä¿¡ãªã©ã®ã«ãŒãã³ã¿ã¹ã¯ãåŠçã§ããäºåå²ãåœãŠã¹ã¬ããã®ããŒã«ãäœæããããšã§ãã
èªåã§ã¹ã¬ãããçæããã³ç Žæ£ããããšãšæ¯èŒããã¹ã¬ããããŒã«ã®ãã1ã€ã®å©ç¹ã¯ãã¹ã¬ããã®
ãªãŒããŒãµãã¹ã¯ãªãã·ã§ã³ ïŒã¹ã¬ããã®æ°ã䜿çšå¯èœãªã³ã¢ã®æ°ãè¶
ããããã»ããµãŒæéã®ããªãã®éšåãã³ã³ããã¹ãã®åãæ¿ãã«è²»ããããç¶æ³ãå¿é
ããå¿
èŠããªãããšã§ãïŒç¿»èš³è
]ïŒã ããã¯ãã·ã¹ãã ã®ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
ããã«ãããŒã«ã䜿çšãããšãã¹ã¬ããã®ã©ã€ããµã€ã¯ã«ã管çããæéãçããæçµçã«ãšã©ãŒã®å°ãªãããã³ã³ãã¯ããªã³ãŒãã«ãªããŸãã
ã¹ã¬ããããŒã«ãå®è£
ãã2ã€ã®æãäžè¬çãªã©ã€ãã©ãªã¯ã
Intelã¹ã¬ãããã«ãã£ã³ã°ãããã¯ïŒTBBïŒãš
Microsoft Parallel Patterns LibraryïŒPPLïŒã§ãã
ãšã©ãŒ12ïŒããã¯ã°ã©ãŠã³ãã¹ã¬ããã§çºçããäŸå€ãåŠçããªã
ããã¹ã¬ããã§ã¹ããŒãããäŸå€ãå¥ã®ã¹ã¬ããã§åŠçããããšã¯ã§ããŸããã äŸå€ãã¹ããŒãã颿°ããããšæ³åããŠã¿ãŸãããã ã¡ã€ã³ã®å®è¡ã¹ã¬ããããåå²ããå¥ã®ã¹ã¬ããã§ãã®é¢æ°ãå®è¡ãã远å ã®ã¹ã¬ããããã¹ããŒãããäŸå€ããã£ãããããšäºæ³ãããå Žåãããã¯æ©èœããŸããã äŸãèããŠã¿ãŸãããïŒ
#include "stdafx.h"
#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>
static std :: exception_ptr teptr = nullptr ;
void LaunchRocket ( )
{
throw std :: runtime_error ( "Catch me in MAIN" ) ;
}
int main ( )
{
try
{
std :: thread t1 ( LaunchRocket ) ;
t1. join ( ) ;
}
catch ( const std :: exception & ex )
{
std :: cout << "Thread exited with exception: " << ex. what ( ) << " \n " ;
}
return 0 ;
}
ãã®ããã°ã©ã ãå®è¡ããããšã¯ã©ãã·ã¥ããŸãããmainïŒïŒé¢æ°ã®catchãããã¯ã¯å®è¡ããããã¹ã¬ããt1ã§ã¹ããŒãããäŸå€ãåŠçããŸããã
ãã®åé¡ã®è§£æ±ºçã¯ãC ++ 11ã®æ©èœã䜿çšããããšã§ã
ãstd:: exception_ptrã䜿çšããŠãããã¯ã°ã©ãŠã³ãã¹ã¬ããã§ã¹ããŒãããäŸå€ãåŠçããŸãã å®è¡ããå¿
èŠãããæé ã¯æ¬¡ã®ãšããã§ãã
- nullptrã«åæåãããstd :: exception_ptrã¯ã©ã¹ã®ã°ããŒãã«ã€ã³ã¹ã¿ã³ã¹ãäœæãã
- å¥ã®ã¹ã¬ããã§å®è¡ããã颿°å
ã§ããã¹ãŠã®äŸå€ãåŠçããåã®æé ã§å®£èšãããã°ããŒãã«å€æ°std :: exception_ptrã®å€std :: current_exceptionïŒïŒãèšå®ããŸã
- ã¡ã€ã³ã¹ã¬ããå
ã®ã°ããŒãã«å€æ°ã®å€ã確èªãã
- å€ãèšå®ãããŠããå Žåã¯ã std :: rethrow_exceptionïŒexception_ptr pïŒé¢æ°ã䜿çšããŠã以åã«ãã£ããããäŸå€ãå床åŒã³åºããåç
§ãšããŠãã©ã¡ãŒã¿ãŒãšããŠæž¡ããŸã
åç
§ã«ããäŸå€ã®åŒã³åºãã¯ããããäœæãããã¹ã¬ããã§ã¯çºçããªãããããã®æ©èœã¯ç°ãªãã¹ã¬ããã§äŸå€ãåŠçããã®ã«æé©ã§ãã
以äžã®ã³ãŒãã§ã¯ãããã¯ã°ã©ãŠã³ãã¹ã¬ããã§ã¹ããŒãããäŸå€ãå®å
šã«åŠçã§ããŸãã
#include "stdafx.h"
#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>
static std :: exception_ptr globalExceptionPtr = nullptr ;
void LaunchRocket ( )
{
try
{
std :: this_thread :: sleep_for ( std :: chrono :: milliseconds ( 100 ) ) ;
throw std :: runtime_error ( "Catch me in MAIN" ) ;
}
catch ( ... )
{
//
globalExceptionPtr = std :: current_exception ( ) ;
}
}
int main ( )
{
std :: thread t1 ( LaunchRocket ) ;
t1. join ( ) ;
if ( globalExceptionPtr )
{
try
{
std :: rethrow_exception ( globalExceptionPtr ) ;
}
catch ( const std :: exception & ex )
{
std :: cout << "Thread exited with exception: " << ex. what ( ) << " \n " ;
}
}
return 0 ;
}
ééã13ïŒstd :: asyncã䜿çšãã代ããã«ãã¹ã¬ããã䜿çšããŠéåææäœãã·ãã¥ã¬ãŒããã
éåæã«å®è¡ããã³ãŒããå¿
èŠãªå Žåãã€ãŸã ã¡ã€ã³ã¹ã¬ããã®å®è¡ããããã¯ããã«ã
std :: asyncïŒïŒã䜿çšããã®ãæè¯ã®éžæã§ãã ããã¯ãã¹ããªãŒã ãäœæãã颿°ã©ã ãã®åœ¢åŒã®é¢æ°ãŸãã¯ãã©ã¡ãŒã¿ãŒãžã®ãã€ã³ã¿ãŒãä»ããŠãã®ã¹ããªãŒã ã«å®è¡ããããã«å¿
èŠãªã³ãŒããæž¡ãããšãšåçã§ãã ãã ããåŸè
ã®å Žåããã®ã¹ã¬ããã§çºçããå¯èœæ§ã®ãããã¹ãŠã®äŸå€ã®åŠçãšåæ§ã«ããã®ã¹ã¬ããã®äœæãæ¥ç¶/åæãç£èŠããå¿
èŠããããŸãã
std :: asyncïŒïŒã䜿çšãããšããããã®åé¡ããè§£æŸããã
ãããããã¯ç¶æ
ã«ãªãå¯èœæ§ã倧å¹
ã«æžå°ããŸãã
std :: asyncã䜿çšãããã1ã€ã®éèŠãªå©ç¹ã¯ã
std :: futureãªããžã§ã¯ãã䜿çšããŠãåŒã³åºãå
ã®ã¹ã¬ããã«éåææäœã®çµæãååŸã§ããããšã§ãã intãè¿ã
ConjureMagicïŒïŒé¢æ°ããããšããŸãã ã¿ã¹ã¯ãå®äºãããšã
æªæ¥ã®ãªããžã§ã¯ãã«å°æ¥ã®å€ãèšå®ããéåææäœãéå§ã§ããæäœã®åŒã³åºãå
ã®å®è¡ãããŒã§ãã®ãªããžã§ã¯ãããå®è¡çµæãæœåºã§ããŸãã
// future
std :: future asyncResult2 = std :: async ( & ConjureMagic ) ;
//... - future
// future
int v = asyncResult2. get ( ) ;
å®è¡äžã®ã¹ã¬ããããåŒã³åºãå
ã«çµæãååŸããããšã¯ãããé¢åã§ãã æ¬¡ã®2ã€ã®æ¹æ³ãå¯èœã§ãã
- åºå倿°ãžã®åç
§ããçµæãä¿åããã¹ããªãŒã ã«æž¡ããŸãã
- çµæãã¯ãŒã¯ãããŒãªããžã§ã¯ãã®ãã£ãŒã«ã倿°ã«ä¿åããŸãããã®å€æ°ã¯ãã¹ã¬ããã®å®è¡ãå®äºãããšããã«èªã¿åãããšãã§ããŸãã
Kurt Guntherothã¯ãããã©ãŒãã³ã¹ã®èгç¹ãããã¹ããªãŒã ãäœæãããªãŒããŒãããã
asyncã䜿çšãããªãŒããŒãããã®14åã§ããããšãçºèŠããŸããã
çµè«ïŒ
std :: threadãçŽæ¥äœ¿çšããããšãæ¯æãã匷åãªåŒæ°ãèŠã€ãããŸã§ãããã©ã«ãã§
std :: asyncïŒïŒã䜿çšããŸãã
ãšã©ãŒ14ïŒéåæãå¿
èŠãªå Žåã¯ãstd :: launch :: asyncã䜿çšããªãã§ãã ãã
std :: asyncïŒïŒé¢æ°ã¯ãããã©ã«ãã§ã¯éåæã«å®è¡ãããªãå¯èœæ§ããããããå®å
šã«æ£ããããã§ã¯ãããŸããïŒ
2ã€ã®
std ::éåæã©ã³ã¿ã€ã ããªã·ãŒããããŸãã
- std :: launch :: async ïŒæž¡ããã颿°ã¯å¥ã®ã¹ã¬ããã§ããã«å®è¡ãéå§ããŸã
- std :: launch :: deferred ïŒæž¡ããã颿°ã¯ããã«ã¯éå§ãããã std :: futureãªããžã§ã¯ãã§getïŒïŒãŸãã¯waitïŒïŒåŒã³åºããè¡ãããåã«ãã®èµ·åãé
å»¶ããã std :: asyncåŒã³åºãããè¿ãããŸãã ãããã®ã¡ãœãããåŒã³åºãããå Žæã§ã颿°ã¯åæçã«å®è¡ãããŸãã
ããã©ã«ãã®ãã©ã¡ãŒã¿ãŒãæå®ããŠ
std :: asyncïŒïŒãåŒã³åºããšãããã2ã€ã®ãã©ã¡ãŒã¿ãŒã®çµã¿åããã§éå§ãããå®éã«ã¯äºæž¬ã§ããªãåäœãçºçããŸãã ããã©ã«ãã®èµ·åããªã·ãŒã§
stdïŒasyncïŒïŒã䜿çšããããšã«ã¯ãä»ã«ãå€ãã®å°é£ã䌎ããŸãã
- ããŒã«ã«ãããŒå€æ°ãžã®æ£ããã¢ã¯ã»ã¹ãäºæž¬ã§ããªã
- getïŒïŒããã³waitïŒïŒã¡ãœããã®åŒã³åºãã¯ããã°ã©ã å®è¡äžã«åŒã³åºãããªãå¯èœæ§ããããããéåæã¿ã¹ã¯ã¯ãŸã£ããéå§ãããªãå¯èœæ§ããããŸã
- çµäºæ¡ä»¶ãstd :: futureãªããžã§ã¯ãã®æºåãã§ããŠããããšãæåŸ
ããã«ãŒãã§äœ¿çšãããå Žåããããã®ã«ãŒãã¯çµäºããªãå¯èœæ§ããããŸãã
ãããã®ãã¹ãŠã®åé¡ãåé¿ããã«ã¯ã
åžžã« std :: launch :: async launchããªã·ãŒã§
std :: asyncãåŒã³åºããŸãã
ãããããªãã§ãã ããïŒ
// myFunction std::async
auto myFuture = std :: async ( myFunction ) ;
代ããã«ããããè¡ããŸãïŒ
// myFunction
auto myFuture = std :: async ( std :: launch :: async , myFunction ) ;
ãã®ç¹ã«ã€ããŠã¯ãã¹ã³ããã»ãã€ã€ãŒãºã®èæžãEffective and Modern C ++ãã§ããã«è©³ããæ€èšãããŠããŸãã
ééã15ïŒstdã®getïŒïŒã¡ãœããã®åŒã³åºã::å®è¡æéãéèŠãªã³ãŒããããã¯å
ã®futureãªããžã§ã¯ã
以äžã®ã³ãŒãã¯ãéåææäœã®
std :: futureãªããžã§ã¯ãããååŸããçµæãåŠçããŸãã ãã ãã
whileã«ãŒãã¯ãéåææäœãå®äºãããŸã§ããã¯ãã
ãŸã ïŒãã®å Žåã10ç§éïŒã ãã®ã«ãŒãã䜿çšããŠç»é¢ã«æ
å ±ã衚瀺ããå ŽåããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ã¬ã³ããªã³ã°ã«äžå¿«ãªé
å»¶ãçºçããå¯èœæ§ããããŸãã
#include "stdafx.h"
#include <future>
#include <iostream>
int main ( )
{
std :: future < int > myFuture = std :: async ( std :: launch :: async , [ ] ( )
{
std :: this_thread :: sleep_for ( std :: chrono :: seconds ( 10 ) ) ;
return 8 ;
} ) ;
//
while ( true )
{
//
std :: cout << "Rendering Data" << std :: endl ;
int val = myFuture. get ( ) ; // 10
// - Val
}
return 0 ;
}
泚 ïŒäžèšã®ã³ãŒãã®ãã1ã€ã®åé¡ã¯ã
std :: futureãªããžã§ã¯ãã®ç¶æ
ãã«ãŒãã®æåã®å埩ã§ååŸãããååŸã§ããªãã£ãã«ããããããã
std :: futureãªããžã§ã¯ãã«2åã¢ã¯ã»ã¹ããããšããããšã§ãã
æ£ãã解決çã¯ã
getïŒïŒã¡ãœãããåŒã³åºãåã«ã
std :: futureãªããžã§ã¯ãã®æå¹æ§ããã§ãã¯ããããšã§ãã ãããã£ãŠãéåæã¿ã¹ã¯ã®å®äºããããã¯ãããæ¢ã«æœåºããã
std :: futureãªããžã§ã¯ãã«
åãåãããããšããŸããã
ãã®ã³ãŒãã¹ããããã䜿çšãããšããããå®çŸã§ããŸãã
#include "stdafx.h"
#include <future>
#include <iostream>
int main ( )
{
std :: future < int > myFuture = std :: async ( std :: launch :: async , [ ] ( )
{
std :: this_thread :: sleep_for ( std :: chrono :: seconds ( 10 ) ) ;
return 8 ;
} ) ;
//
while ( true )
{
//
std :: cout << "Rendering Data" << std :: endl ;
if ( myFuture. valid ( ) )
{
int val = myFuture. get ( ) ; // 10
// - Val
}
}
return 0 ;
}
â16: , , , std::future::get()
次ã®ã³ãŒããã©ã°ã¡ã³ãããããšæ³åããŠãã ãããstd:: future :: getïŒïŒãåŒã³åºããçµæã¯ã©ããªããšæããŸããïŒããã°ã©ã ãã¯ã©ãã·ã¥ãããšæãããå Žå-ããªãã¯çµ¶å¯Ÿã«æ£ããã§ãïŒéåææäœã§ã¹ããŒãããäŸå€ã¯ãstd :: futureãªããžã§ã¯ãã§getïŒïŒã¡ãœãããåŒã³åºãããå Žåã«ã®ã¿ã¹ããŒãããŸãããŸããgetïŒïŒã¡ãœãããåŒã³åºãããªãå Žåãstd :: futureãªããžã§ã¯ããã¹ã³ãŒãå€ã«ãªããšãäŸå€ã¯ç¡èŠãããŠã¹ããŒãããŸããããªãã®éåææäœãäŸå€ãæããããšãã§ããå Žåã¯ããã€ã§ãã³ãŒã«ã©ããããå¿
èŠãããã®std ::æªæ¥:: GETïŒïŒå
ã®try / catchã®ãããã¯ãããããã©ã®ããã«èŠãããã®äŸïŒ#include "stdafx.h"
#include <future>
#include <iostream>
int main ( )
{
std :: future < int > myFuture = std :: async ( std :: launch :: async , [ ] ( )
{
throw std :: runtime_error ( "Catch me in MAIN" ) ;
return 8 ;
} ) ;
if ( myFuture. valid ( ) )
{
int result = myFuture. get ( ) ;
}
return 0 ;
}
#include "stdafx.h"
#include <future>
#include <iostream>
int main ( )
{
std :: future < int > myFuture = std :: async ( std :: launch :: async , [ ] ( )
{
throw std :: runtime_error ( "Catch me in MAIN" ) ;
return 8 ;
} ) ;
if ( myFuture. valid ( ) )
{
try
{
int result = myFuture. get ( ) ;
}
catch ( const std :: runtime_error & e )
{
std :: cout << "Async task threw exception: " << e. what ( ) << std :: endl ;
}
}
return 0 ;
}
â17: std::async,
ãã®std ::éåæïŒïŒã¯ãã»ãšãã©ã®ã±ãŒã¹ã§ååã§ããããªãã¯ãã¹ããªãŒã ã§ããªãã®ã³ãŒãã®å®è¡äžã®æ³šææ·±ãç£èŠãå¿
èŠãªå¯èœæ§ã®ããç¶æ³ããããŸããããšãã°ãç¹å®ã®ã¹ã¬ããããã«ãããã»ããµã·ã¹ãã ïŒXboxãªã©ïŒã®ç¹å®ã®ããã»ããµã³ã¢ã«ãã€ã³ãããå Žåãæå®ãããã³ãŒããã©ã°ã¡ã³ãã¯ãã·ã¹ãã å
ã®5çªç®ã®ããã»ããµã³ã¢ãžã®ã¹ã¬ããã®ãã€ã³ãã確ç«ããŸããããã¯ãstd :: threadãªããžã§ã¯ãã®native_handleïŒïŒã¡ãœãããšãWin32 APIã¹ããªãŒã 颿°ã«æž¡ãããšã§å¯èœã§ããã¹ããªãŒãã³ã°Win32 APIã«ã¯ãstd :: threadãŸãã¯std :: asyncïŒïŒã§å©çšã§ããªãæ©èœãä»ã«ããããããããŸããäœæ¥ãããšã#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <thread>
using namespace std ;
void LaunchRocket ( )
{
cout << "Launching Rocket" << endl ;
}
int main ( )
{
thread t1 ( LaunchRocket ) ;
DWORD result = :: SetThreadIdealProcessor ( t1. native_handle ( ) , 5 ) ;
t1. join ( ) ;
return 0 ;
}
std :: asyncïŒïŒããããã®åºæ¬çãªãã©ãããã©ãŒã 颿°ã¯äœ¿çšã§ããªãããããã®ã¡ãœããã¯ããè€éãªã¿ã¹ã¯ã«ã¯é©ããŠããŸãããå¥ã®æ¹æ³ã¯ãstd :: packaged_taskãäœæããã¹ã¬ããã®ããããã£ãèšå®ããåŸãç®çã®å®è¡ã¹ã¬ããã«ç§»åããããšã§ããééã18ïŒã³ã¢ãå©çšã§ãããããã¯ããã«å€ãã®ãå®è¡äžã®ãã¹ã¬ãããäœæãã
ã¢ãŒããã¯ãã£ã®èгç¹ããããããŒã¯ãå®è¡äžããšãåŸ
æ©äžãã®2ã€ã®ã°ã«ãŒãã«åé¡ã§ããŸããå®è¡äžã®ã¹ã¬ããã¯ãå®è¡äžã®ã«ãŒãã«ã®ããã»ããµæéã®100ïŒ
ãå©çšããŸããè€æ°ã®å®è¡äžã®ã¹ã¬ããã1ã€ã®ã³ã¢ã«å²ãåœãŠããããšãCPU䜿çšå¹çãäœäžããŸãã 1ã€ã®ããã»ããµã³ã¢ã§è€æ°ã®å®è¡äžã®ã¹ã¬ãããå®è¡ããŠãããã©ãŒãã³ã¹ã¯åäžããŸãããå®éã远å ã®ã³ã³ããã¹ãåãæ¿ãã«ããããã©ãŒãã³ã¹ãäœäžããŸããåŸ
æ©ã¹ã¬ããã¯ãã·ã¹ãã ã€ãã³ãããããã¯ãŒã¯I / Oãªã©ãåŸ
æ©ããŠããéã«å®è¡ãããæ°ã¯ããã¯ãµã€ã¯ã«ã®ã¿ã䜿çšããŸãããã®å Žåãã«ãŒãã«ã®å©çšå¯èœãªããã»ããµãŒæéã®ã»ãšãã©ã¯æªäœ¿çšã®ãŸãŸã§ãã 1ã€ã®åŸ
æ©ã¹ã¬ããã¯ããŒã¿ãåŠçã§ããä»ã®ã¹ã¬ããã¯ã€ãã³ãã®ããªã¬ãŒãåŸ
æ©ããŠããŸããããããè€æ°ã®åŸ
æ©ã¹ã¬ããã1ã€ã®ã³ã¢ã«åæ£ããããšãæå©ãªçç±ã§ããã³ã¢ããšã«è€æ°ã®ä¿çäžã®ã¹ã¬ãããã¹ã±ãžã¥ãŒã«ãããšãããã°ã©ã ã®ããã©ãŒãã³ã¹ã倧å¹
ã«åäžããŸããããã§ã¯ãã·ã¹ãã ããµããŒãããå®è¡äžã®ã¹ã¬ããã®æ°ãã©ã®ããã«çè§£ããã®ã§ããããïŒstd :: thread :: hardware_concurrencyïŒïŒã¡ãœããã䜿çšããŸããéåžžããã®é¢æ°ã¯ããã»ããµã³ã¢ã®æ°ãè¿ããŸããã2ã€ä»¥äžã®è«çã³ã¢ã®ããã«åäœããã³ã¢ãèæ
®ã«å
¥ããŸãgipertredingaãã¿ãŒã²ãããã©ãããã©ãŒã ã®ååŸå€ã䜿çšããŠãããã°ã©ã ã§åæã«å®è¡ãããã¹ã¬ããã®æå€§æ°ãèšç»ããå¿
èŠããããŸããä¿çäžã®ãã¹ãŠã®ã¹ã¬ããã«1ã€ã®ã³ã¢ãå²ãåœãŠãã¹ã¬ããã®å®è¡ã«æ®ãã®ã³ã¢æ°ã䜿çšããããšãã§ããŸããããšãã°ãã¯ã¢ããã³ã¢ã·ã¹ãã ã§ã¯ããã¹ãŠã®ä¿çäžã®ã¹ã¬ããã«1ã€ã®ã³ã¢ã䜿çšããæ®ãã®3ã€ã®ã³ã¢ã«3ã€ã®å®è¡äžã®ã¹ã¬ããã䜿çšããŸããã¹ã¬ããã¹ã±ãžã¥ãŒã©ã®å¹çã«å¿ããŠãå®è¡å¯èœã¹ã¬ããã®äžéšã¯ïŒããŒãžã¢ã¯ã»ã¹ã®å€±æãªã©ã«ããïŒã³ã³ããã¹ããåãæ¿ããã«ãŒãã«ããã°ããéã¢ã¯ãã£ãã®ãŸãŸã«ããå ŽåããããŸãããããã¡ã€ãªã³ã°äžã«ãã®ç¶æ³ã芳å¯ããå Žåãå®è¡ããã¹ã¬ããã®æ°ãã³ã¢ã®æ°ããããããã«å€ãäœæãããã®å€ãã·ã¹ãã ã«æ§æããå¿
èŠããããŸããééã19ïŒåæã«volatileããŒã¯ãŒãã䜿çšãã
volatileããŒã¯ãŒãã¯ã倿°ã®ã¿ã€ããæå®ããåã«ããã®å€æ°ã«å¯Ÿããæäœãã¢ãããã¯ãŸãã¯ã¹ã¬ããã»ãŒãã«ããŸãããããããå¿
èŠãªã®ã¯std :: atomicã§ãã詳现ã«ã€ããŠã¯ãstackoverflowã®èª¬æãåç
§ããŠãã ãããééã20ïŒçµ¶å¯Ÿã«å¿
èŠã§ãªãéããLock Free Architectureã䜿çšãã
ãã¹ãŠã®ãšã³ãžãã¢ã奜ãè€éãªãã®ããããŸããããã¯ãªãã§åäœããããã°ã©ã ãäœæããããšã¯ããã¥ãŒããã¯ã¹ãæ¡ä»¶å€æ°ãéåæãªã©ã®åŸæ¥ã®åæã¡ã«ããºã ãšæ¯èŒããŠéåžžã«é
åçã§ããããããç§ã話ããçµéšè±å¯ãªC ++éçºè
ã¯çæèŠããããŸãããåæãªãã·ã§ã³ãšããŠéããã¯ããã°ã©ãã³ã°ã䜿çšããããšã¯ãæãäžé©åãªæç¹ã§æšªåãã«ãªãå¯èœæ§ãããäžçš®ã®ææå°æ©ãªæé©åã§ãïŒå®å
šãªããŒããã³ãããªãå Žåã®ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã¯ã©ãã·ã¥ã«ã€ããŠèããŠãã ããïŒïŒãC ++ã§ã®ç§ã®ãã£ãªã¢ã§ã¯ãããã¯ã®ãªãã³ãŒãã®å®è¡ãå¿
èŠãšããç¶æ³ã¯1ã€ã ãã§ãããããã¯ããªãœãŒã¹ãéãããã·ã¹ãã ã§äœæ¥ããã³ã³ããŒãã³ãã®åãã©ã³ã¶ã¯ã·ã§ã³ã10ãã€ã¯ãç§ä»¥å
ã§æžãããã§ãããããã¯ããã«éçºã¢ãããŒããé©çšããããšãèããåã«ã3ã€ã®è³ªåã«çããŠãã ããã- åæã¡ã«ããºã ãå¿
èŠãšããªãããã«ã·ã¹ãã ã®ã¢ãŒããã¯ãã£ãèšèšããããšããŸãããïŒååãšããŠãæè¯ã®åæã¯åæã®æ¬ åŠã§ãã
- åæãå¿
èŠãªå Žåãããã©ãŒãã³ã¹ç¹æ§ãçè§£ããããã«ã³ãŒãã®ãããã¡ã€ã«ãäœæããŸãããïŒãããããªããããã«ããã¯ãæé©åããããšããŸãããïŒ
- åçŽã«ã¹ã±ãŒãªã³ã°ãã代ããã«æ°Žå¹³ã«ã¹ã±ãŒãªã³ã°ã§ããŸããïŒ
èŠçŽãããšãéåžžã®ã¢ããªã±ãŒã·ã§ã³éçºã§ã¯ãä»ã®ãã¹ãŠã®éžæè¢ã䜿ãæãããå Žåã«ã®ã¿ãéããã¯ããã°ã©ãã³ã°ãæ€èšããŠãã ããããããèŠããã1ã€ã®æ¹æ³ã¯ãäžèšã®19åã®ãšã©ãŒã®ããã€ãããŸã äœæããŠããå Žåããããããããã¯ããã«ããã°ã©ãã³ã°ããé¢ããå¿
èŠããããšããããšã§ãã[ããã翻蚳è
ïŒãã®èšäºã®æºåãæäŒã£ãŠãããvovo4Kã«æè¬ããŸãã]