c++ - لماذا يتم إرجاع destructor من مستقبل من حظر "std:: متزامن"؟



multithreading c++11 (1)

حجب destructors للعقود الآجلة التي أرجعها std :: المتزامن والخيوط: هذا موضوع مثير للجدل. تعكس قائمة الأوراق التالية بالترتيب الزمني بعض المناقشات التي أجراها أعضاء اللجنة:

على الرغم من أنه كان هناك الكثير من النقاش ، لا توجد تغييرات مخطط لها لـ C ++ 14 بخصوص سلوك المنع للمدمرين في std :: future و std :: thread .

فيما يتعلق بسؤالك ، ربما تكون الورقة الأكثر إثارة للاهتمام هي الورقة الثانية لهان بويم. أقتبس بعض الأجزاء للإجابة على سؤالك.

N3679: يجب أن تنتظر destencors مستقبل Async ()

عودة إلى الأعلى [..] Futures التي يتم إرجاعها بواسطة async() مع نهج تشغيل async الانتظار في destructor الخاصة بهم الحالة المشتركة المقترنة لتصبح جاهزة. هذا يمنع الحالة التي يستمر فيها مؤشر الترابط المقترن في العمل ، ولم يعد هناك وسيلة للانتظار حتى يكتمل بسبب تدمير المستقبل المرتبط. وبدون بذل جهود بطولية لانتظار الانتهاء ، يمكن لمثل هذا الخيط "البعيد" الاستمرار في تجاوز عمر الأشياء التي يعتمد عليها.

[مثال]

من المحتمل أن تكون النتيجة النهائية عبارة عن "ذاكرة مائلة". يتم تجنب هذه المشكلة بالطبع إذا تم استدعاء get() أو wait() [..] قبل أن يتم تدمير [العقود الآجلة]. تتمثل الصعوبة [..] في أن استثناء غير متوقع قد يتسبب في تجاوز هذا الرمز. وبالتالي هناك حاجة عادة إلى نوع من حارس نطاق لضمان السلامة. إذا نسي المبرمج إضافة حارس نطاق ، فمن المحتمل أن المهاجم يمكن أن يولد على سبيل المثال استثناء bad_alloc في نقطة مناسبة للاستفادة من الرقابة ، وتسبب تكديس المكدس. قد يكون من الممكن أيضًا التحكم في البيانات المستخدمة للكتابة فوق الحزمة ، وبالتالي التحكم في العملية. هذا خطأ دقيق بما فيه الكفاية ، من وجهة نظرنا ، من المرجح أن يتم إغفاله في الكود الحقيقي.

تحديث: يحتوي تقرير رحلة مايكل وونغ أيضًا على بعض المعلومات المثيرة للاهتمام فيما يتعلق بنتائج الاجتماع في سبتمبر 2013:

The View from the C ++ Standard meeting September 2013 Part 2 of 2.

حول المسألة التي لا ينبغي أن يمنعها الهدامون المتعصبون ، خصصنا الكثير من النقاش حولها. [..] كان الموقف الوحيد الذي حظي بتأييد كبير هو [..] إعطاء الاستشارات بأن المدمرين المستقبليين لن يمنعهم ، ما لم يتم إعادتهم من المتزامن ، مما يجعله الاستثناء الملحوظ. [..] بعد مناقشة مهمة ، كان الجزء الوحيد الذي حاولنا حمله هو N3776 ، محاولة لتوضيح الموقف بأن ~future و ~shared_future لا ~shared_future إلا في وجود التزامن. كانت هناك محاولة لإصدار إهمال على غرار سيرة C. Deprecate بدون استبدال. تم طرح هذا الاقتراح في الواقع تقريبًا. لكن [..] مات حتى قبل أن يصل إلى طاولة العمليات.

عند محاولة الإجابة عن سؤال آخر Stackoverflow ، أدركت أن مقتطف C ++ 11 البسيط هذا يحظر ضمنيًا مؤشر ترابط الاستدعاء:

std::async(std::launch::async, run_async_task)

بالنسبة لي هذا قد يبدو طريقة C ++ 11 الكنسي لإطلاق مهمة بشكل غير متزامن دون الاهتمام بالنتيجة. بدلاً من ذلك ، يجب على المرء بوضوح أن ينشئ ويفصل الخيط (انظر answer على السؤال المذكور) من أجل تحقيق ذلك.

إذن ھﻧﺎ ﺳؤاﻟﻲ: ھل ھﻧﺎك أي ﺳﺑب ﻓﻲ ﻣﺎ ﯾﺗﻌﻟق ﺑﺎﻟﺳﻼﻣﺔ / اﻟﺻﺣﯾﺢ اﻟذي ﯾﺟب أن ﯾﻌوق ﻣُﮭﯾ ofر std::future ؟ ألن يكون ذلك كافيًا إذا تم منعه من get هو غير ذلك ، وإذا لم أكن مهتمًا بقيمة الاسترجاع أو الاستثناء ، فببساطة ، هل يتم إطلاق النار والنسيان؟





std