ΪʲôҪʹÓà std::async?

ʱ¼ä£º2023-03-09
±¾ÎĽéÉÜÁËΪʲôҪʹÓà std::async?µÄ´¦Àí·½·¨£¬¶Ô´ó¼Ò½â¾öÎÊÌâ¾ßÓÐÒ»¶¨µÄ²Î¿¼¼ÛÖµ£¬ÐèÒªµÄÅóÓÑÃÇÏÂÃæËæןú°æÍøµÄС±àÀ´Ò»Æðѧϰ°É£¡

ÎÊÌâÃèÊö

ÎÒÕýÔÚ³¢ÊÔÉîÈë̽Ë÷РC++11 ±ê×¼µÄËùÓÐÑ¡ÏͬʱʹÓà std::async ²¢ÔĶÁÆ䶨Ò壬ÎÒ×¢Òâµ½Á½¼þÊ£¬ÖÁÉÙÔÚ´øÓÐ gcc 4.8.1 µÄ linux ÏÂ:

I'm trying to explore all the options of the new C++11 standard in depth, while using std::async and reading its definition, I noticed 2 things, at least under linux with gcc 4.8.1 :

  • Ëü±»³ÆΪasync£¬µ«ËüÓÐÒ»¸öÕæÕýµÄ˳ÐòÐÐΪ"£¬»ù±¾ÉÏÔÚÄãµ÷ÓÃÓëÄãµÄÒì²½º¯Êýfoo<Ïà¹ØµÄδÀ´µÄÄÇÒ»ÐÐ/em>£¬³ÌÐò»á×èÈû£¬Ö±µ½ foo Ö´ÐÐÍê³É.
  • ËüÒÀÀµÓÚÓëÆäËûÍêÈ«ÏàͬµÄÍⲿ¿â£¬ÒÔ¼°¸üºÃµÄ·Ç×èÈû½â¾ö·½°¸£¬ÕâÒâζ×Å pthread£¬Èç¹ûÄãÏëʹÓà std::async ÄãÐèÒªÏß³Ì.
  • it's called async, but it got a really "sequential behaviour", basically in the row where you call the future associated with your async function foo, the program blocks until the execution of foo it's completed.
  • it depends on the exact same external library as others, and better, non-blocking solutions, which means pthread, if you want to use std::async you need pthread.

ÔÚÕâÒ»µãÉÏ£¬ÎÒºÜ×ÔÈ»µØÎÊΪʲôѡÔñ std::async ¶ø²»ÊÇÒ»×é¼òµ¥µÄº¯×Ó?ÕâÊÇÒ»¸ö¸ù±¾ÎÞ·¨À©Õ¹µÄ½â¾ö·½°¸£¬Äúµ÷ÓõÄδÀ´Ô½¶à£¬ÄúµÄ³ÌÐòÏìÓ¦¾ÍÔ½Âý.

at this point it's natural for me asking why choosing std::async over even a simple set of functors ? It's a solution that doesn't even scale at all, the more future you call, the less responsive your program will be.

ÎÒ´í¹ýÁËʲôÂð?ÄúÄÜ·ñչʾһ¸öÔÊÐíÒÔÒì²½¡¢·Ç×èÈû·½Ê½Ö´ÐеÄʾÀý?

Am I missing something ? Can you show an example that is granted to be executed in an async, non blocking, way ?

ÍƼö´ð°¸

Èç¹ûÄúÐèÒªÒì²½²Ù×÷µÄ½á¹û£¬ÄÇôÄú±ØÐë×èÈû£¬ÎÞÂÛÄúʹÓÃʲô¿â.Õâ¸öÏë·¨ÊÇÄã¿ÉÒÔÑ¡ÔñºÎʱ×èÖ¹£¬²¢ÇÒÏ£Íûµ±ÄãÕâÑù×öʱ£¬Äã×èÖ¹µÄʱ¼ä¿ÉÒÔºöÂÔ²»¼Æ£¬ÒòΪËùÓеŤ×÷¶¼ÒѾ­Íê³É.

If you need the result of an asynchronous operation, then you have to block, no matter what library you use. The idea is that you get to choose when to block, and, hopefully when you do that, you block for a negligible time because all the work has already been done.

ÁíÇë×¢Ò⣬std::async ¿ÉÒÔͨ¹ý²ßÂÔ std::launch::async »ò std::launch::deferred Æô¶¯>.Èç¹û²»Ö¸¶¨£¬ÔòÔÊÐíʵÏÖÑ¡Ôñ£¬²¢ÇҺܿÉÄÜÑ¡ÔñʹÓÃÑÓ³ÙÇóÖµ£¬Õâ»áµ¼Öµ±Äú³¢ÊÔ´ÓδÀ´»ñÈ¡½á¹ûʱ£¬ËùÓй¤×÷¶¼ÒÑÍê³É£¬´Ó¶øµ¼Ö¸ü³¤µÄ¿é.Òò´Ë£¬Èç¹ûÄúÏëÈ·±£Òì²½Íê³É¹¤×÷£¬ÇëʹÓà std::launch::async.

Note also that std::async can be launched with policies std::launch::async or std::launch::deferred. If you don't specify it, the implementation is allowed to choose, and it could well choose to use deferred evaluation, which would result in all the work being done when you attempt to get the result from the future, resulting in a longer block. So if you want to make sure that the work is done asynchronously, use std::launch::async.

Õâƪ¹ØÓÚΪʲôҪʹÓà std::async?µÄÎÄÕ¾ͽéÉܵ½ÕâÁË£¬Ï£ÍûÎÒÃÇÍƼöµÄ´ð°¸¶Ô´ó¼ÒÓÐËù°ïÖú£¬Ò²Ï£Íû´ó¼Ò¶à¶àÖ§³Ö¸ú°æÍø£¡