2015-01-21 7 views
7

मानक के संभाजक लेने कंस्ट्रक्टर्स promise/packaged_task सिर्फ राज्य वस्तु खुद के लिए संभाजक का उपयोग करने वाले हैं, या इस सभी (आंतरिक) से संबंधित वस्तुओं के लिए गारंटी की जानी चाहिए?कस्टम allocators बनाम वादों और पैक कार्यों

[futures.promise]: "... साझा राज्य के लिए स्मृति को आबंटित"
[futures.task.members]: "... आंतरिक डाटा संरचनाओं की दुकान करने के लिए आवश्यक स्मृति को आबंटित"

विशेष रूप से, नीचे दी गई बग या विशेषताएं हैं?

* MSVC 2013.4, बूस्ट 1.57, short_alloc.h by Howard Hinnant

उदाहरण 1

#define BOOST_THREAD_VERSION 4 
#include <boost/thread/future.hpp> 
#include "short_alloc.h" 
#include <cstdio> 

void *operator new(std::size_t s) { 
    printf("alloc %Iu\n", s); 
    return malloc(s); 
} 

void operator delete(void *p) { 
    free(p); 
} 

int main() { 

    const int N = 1024; 
    arena<N> a; 
    short_alloc< int, N > al(a); 

    printf("[promise]\n"); 
    auto p = boost::promise<int>(std::allocator_arg, al); 
    p.set_value(123); 

    printf("[packaged_task]\n"); 
    auto q = boost::packaged_task< int() >(std::allocator_arg, al, [] { return 123; }); 
    q(); 

    return 0; 

} 

आउटपुट:

... 
[promise] 
alloc 8 
alloc 12 
alloc 8 
alloc 24 
[packaged_task] 
alloc 8 
alloc 12 
alloc 8 
alloc 24 

Fwiw, डिफ़ॉल्ट संभाजक साथ उत्पादन

... 
[promise] 
alloc 144 
alloc 8 
alloc 12 
alloc 8 
alloc 16 
[packaged_task] 
alloc 160 
alloc 8 
alloc 12 
alloc 8 
alloc 16 
है

उदाहरण 2

AFAICT, MSVC के std::mutex एक अपरिहार्य ढेर आवंटन करता है, और इसलिए, ताकि std::promise जो इसे इस्तेमाल करता है। क्या यह एक अनुरूप व्यवहार है?

+4

आप अपने नमूना कोड में 'बूस्ट' का उपयोग क्यों कर रहे हैं, और 'std' द्वारा निर्दिष्ट व्यवहार के बारे में बात कर रहे हैं? 'Std' का उपयोग क्यों नहीं करें? – Yakk

+1

@Yakk: http://www.boost.org/doc/libs/1_57_0/doc/html/thread/compliance.html – vpozdyayev

+0

@Yakk: इसके अलावा, मैंने std कोशिश की; उदाहरण 2 देखें। दरअसल, मैंने पहले std की कोशिश की, फिर कस्टम आवंटक के अधिक उपयोग की उम्मीद में बढ़ावा देने के लिए बदल गया --- लेकिन हां। – vpozdyayev

उत्तर

1

एनबी। आपके कोड के साथ कुछ समस्याएं हैं। सी ++ 14 में यदि आप operator delete(void*) को प्रतिस्थापित करते हैं तो आपको operator delete(void*, std::size)t) को भी बदलना होगा। आप को देखने के लिए एक सुविधा परीक्षण मैक्रो का उपयोग कर सकते हैं संकलक की आवश्यकता है कि:

void operator delete(void *p) { 
    free(p); 
} 
#if __cpp_sized_deallocation 
// Also define sized-deallocation function: 
void operator delete(void *p, std::size_t) { 
    free(p); 
} 
#endif 

दूसरे size_t के लिए सही printf फॉर्मेट स्पेसिफायर zu नहीं u है, तो आप %Izu का उपयोग करना चाहिए।

AFAICT, MSVC के std::mutex एक अपरिहार्य ढेर आवंटन करता है, और इसलिए, ताकि std::promise जो इसे इस्तेमाल करता है। क्या यह एक अनुरूप व्यवहार है?

यह निश्चित रूप से संदिग्ध है कि std::mutex गतिशील आवंटन का उपयोग करना चाहिए। इसका कन्स्ट्रक्टर नहीं कर सकता, क्योंकि यह constexpr होना चाहिए। यह lock() या try_lock() लेकिन lock() करने के लिए पहली कॉल जब तक आवंटन में देरी हो सकती एक वैध त्रुटि स्थिति के रूप में संसाधनों के अधिग्रहण की विफलता की सूची नहीं है, और इसका मतलब try_lock() अगर यह संसाधनों की जरूरत है यह आवंटित नहीं कर सकता एक uncontended म्युटेक्स लॉक करने के लिए विफल हो सकता है । इसकी अनुमति है, अगर आप इसे घुमाते हैं, लेकिन आदर्श नहीं है।

लेकिन, अपने मुख्य प्रश्न के बारे में के रूप में आप उद्धृत किया, मानक केवल promise के लिए इस का कहना है:

दूसरे निर्माता साझा राज्य के लिए स्मृति को आबंटित करने संभाजक a उपयोग करता है।

यह वचन के अनुसार अन्य संसाधनों के बारे में कुछ भी नहीं कहता है। यह मानना ​​उचित है कि म्यूटेक्स जैसी कोई भी सिंक्रनाइज़ेशन ऑब्जेक्ट्स साझा स्थिति का हिस्सा हैं, वादा नहीं, लेकिन उस शब्द को यह आवश्यक नहीं है कि आवंटक को साझा राज्य के सदस्यों की आवश्यकता के लिए उपयोग किया जाता है, केवल साझा राज्य द्वारा आवश्यक स्मृति के लिए अपने आप।

packaged_task के लिए शब्द व्यापक है और यह दर्शाता है कि सभी आंतरिक राज्यों को आवंटक का उपयोग करना चाहिए, हालांकि यह तर्क दिया जा सकता है कि इसका मतलब यह है कि आवंटित कार्य संग्रहीत कार्य और साझा स्थिति के लिए स्मृति प्राप्त करने के लिए उपयोग किया जाता है, लेकिन फिर से उस सदस्य साझा राज्य को आवंटक का उपयोग करने की आवश्यकता नहीं है।

सारांश में, मुझे नहीं लगता कि मानक 100% स्पष्ट MSVC कार्यान्वयन की अनुमति है या नहीं है, लेकिन है कि कैसे libstdC++ <future> कार्यान्वयन काम करता है IMHO एक कार्यान्वयन कि malloc या new से अतिरिक्त मेमोरी की जरूरत नहीं है बेहतर है (और)।

संबंधित मुद्दे