2016-11-24 15 views
5

मैं मानक पर्यावरण यहाँ साथ टाइमर को लागू करने की कोशिश कर रहा हूँ एक कोड मैं है:टाइमर मुख्य थ्रेड लटकी हुई है

bool shutdownDetected = false; 

void signal_handler(const int sigid) 
{ 
    shutdownDetected = true; 
} 

int main(int argc, const char * argv[]) 
{ 
    signal(SIGTERM, (sig_t)signal_handler); 

    std::async(std::launch::async, [&]() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

    std::cout << "main function" << std::endl; 

    while (!shutdownDetected) { 
    } 

    return EXIT_SUCCESS; 
} 

परिणाम के रूप में मैं 5 सेकंड के बाद उत्पादन में देखें:

// 5 seconds left 
On Timer 
main function 

लेकिन देखना चाहते हैं:

main function 
// 5 seconds left 
On Timer 

ऐसा लगता है कि मेरा कार्यान्वयन मुख्य धागा भी लटकता है। इससे कैसे बचें?

+1

मैं कोई विशेषज्ञ हूँ, लेकिन मैं पर यह अजीब लगा कि आप कॉल '.Get (न पाते हैं)' [ 'std :: future'] (http://en.cppreference.com/w/cpp/धागा/भविष्य)। [जो आप करते हैं तो इच्छित परिणाम देता है।] (http://coliru.stacked-crooked.com/a/f04caae880926851) – Borgleader

+0

वास्तव में 'get'' को कॉल करने की भी आवश्यकता नहीं है। बस 'भविष्य' को किसी चीज़ को असाइन करने की आवश्यकता है ताकि आप बाद में – user4581301

+0

@ user4581301 ओहह कह सकें, क्योंकि अस्थायी तुरंत नष्ट हो जाता है और सीट के होने से पहले मुख्य धागे को लटका दिया जाता है? – Borgleader

उत्तर

3

आपका std :: async आदेश एक std :: भविष्य है, जो तब तुरंत नष्ट हो जाता है देता है। समस्या यह है कि भविष्य के विनाश में आपके द्वारा बनाए गए धागे में शामिल होना शामिल है, जिसका अर्थ यह है कि विनाशक तब तक इंतजार कर रहा है जब तक धागा स्वयं समाप्त नहीं हो जाता है और आपके मुख्य धागे में कोड निष्पादन तब तक आगे नहीं बढ़ता जब तक कि प्रक्रिया पूरी नहीं हो जाती।

सरल जवाब एक चर करने के लिए अपने std :: async कॉल का परिणाम असाइन करें और संभवतः अपने पाश कि समाप्ति के लिए परीक्षण में अपनी get() सदस्य फ़ंक्शन को कॉल करने के लिए है। जब तक आप std::future एक चर के लिए std::async द्वारा दिया निर्दिष्ट करेंगे और उसके चारों ओर रखने

auto t = std::async(std::launch::async, [&]() { 
    std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
    std::cout << "On TIMER!" << std::endl; 
}); 

std::cout << "main function" << std::endl; 

t.get(); 
3
std::async(std::launch::async, [&]() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

काम नहीं करता। मुझे नहीं पता था कि यह क्यों है, स्पष्ट रूप से क्योंकि मुझे इसे देखने के लिए परेशान नहीं किया जा सका। विन्सेंट Savard किया था, और destructor for std::future जो कहते हैं पर दस्तावेजीकरण करने के लिए हमें जुड़ा हुआ:

रोक सकते निम्न बात कर रहे हैं के सभी करता है, तो: साझा राज्य एक फोन द्वारा बनाया गया था एसटीडी :: async, साझा राज्य है अभी तक तैयार नहीं है, और यह साझा राज्य का अंतिम संदर्भ था।

चूंकि returnded std::future किसी भी चीज़ को असाइन नहीं किया गया है, तो इसे तुरंत नष्ट कर दिया जाता है और विनाशक पूर्ण होने तक अवरुद्ध हो जाता है।

मैं सिग्नल हैंडलर छोड़ने जा रहा हूं क्योंकि यह समस्या से प्रासंगिक नहीं है।

#include <iostream> 
#include <future> 

int main() 
{ 
    auto letMeLive = std::async(std::launch::async, []() { 
     std::this_thread::sleep_for(std::chrono::milliseconds{5000}); 
     std::cout << "On TIMER!" << std::endl; 
    }); 

    std::cout << "main function" << std::endl; 

    letMeLive.wait(); // instead of the signal handler 
    return EXIT_SUCCESS; 
} 
संबंधित मुद्दे