2012-05-28 11 views
5

मैं थ्रेडिंग बूस्ट करने के लिए नया हूं और मैं कई धागे से आउटपुट कैसे किया जाता है इसके साथ अटक गया हूं। मेरे पास एक साधारण बढ़ावा है :: धागा 9 से 1 तक गिर रहा है; मुख्य धागा इंतजार करता है और फिर प्रिंट करता है "लिफ्टऑफ .. !!"बूस्ट थ्रेडिंग: कॉउट व्यवहार

#include <iostream> 
#include <boost/thread.hpp> 
using namespace std; 

struct callable { 
    void operator()(); 
}; 

void callable::operator()() { 
    int i = 10; 
    while(--i > 0) { 
     cout << "#" << i << ", "; 
     boost::this_thread::yield(); 
    } 
    cout.flush(); 
} 

int main() { 
    callable x; 
    boost::thread myThread(x); 

    myThread.join(); 

    cout << "LiftOff..!!" << endl; 

    return 0; 
} 

समस्या यह है कि मुझे आउटपुट प्रदर्शित करने के लिए मेरे धागे में एक स्पष्ट "cout.flush()" कथन का उपयोग करना होगा। अगर मैं फ्लश() का उपयोग नहीं करता, तो मुझे केवल "लिफ्टऑफ !!" मिलता है आउटपुट के रूप में।

क्या कोई सलाह दे सकता है कि मुझे स्पष्ट रूप से फ्लश() का उपयोग क्यों करना है?

+1

मेरे लिए फ्लश() '(लिनक्स 3.0.6, जीसीसी 4.5.3, 1.46 बढ़ाएं) के साथ या बिना मेरे लिए उसी तरह से व्यवहार करता है। – delicateLatticeworkFever

+0

एफडब्ल्यूआईडब्ल्यू, मैंने Win7x64 (MSVC10) पर अपने प्रोग्राम का परीक्षण किया, और यह फ्लश() के बिना संख्याओं को प्रिंट करता है। ओम आप ​​किस मंच का परीक्षण करते हैं? –

+0

@ कोनराड रुडॉल्फ: "दौड़ की स्थिति" दो अलग-अलग स्टडआउट बफर नहीं बनाएगी, जो कि एकमात्र कल्पनीय स्पष्टीकरण है कि क्यों मुख्य रूप से 'एंडल' एक जुड़ा हुआ थ्रेड पर प्रतीक्षा करने के बाद फ्लश नहीं करता है। (उल्लेख नहीं है: यहां कोई भी "दौड़ की स्थिति" नहीं है, केवल दो धागे हैं और एक दूसरे पर इंतजार कर रहा है।) – delicateLatticeworkFever

उत्तर

5

यह विशेष रूप से अदालत धागा आधार और केवल उत्पादन प्रति एक पर आमतौर पर बफ़र के रूप में संबंधित सूत्र नहीं है, जब कार्यान्वयन का फैसला करता है - धागा उत्पादन में तो केवल कार्यान्वयन विशिष्ट आधार पर दिखाई देगा - फ्लश को कॉल करके आप बफर को फ़्लश करने के लिए मजबूर कर रहे हैं।

यह कार्यान्वयन में भिन्न होगा - आमतौर पर यह कुछ निश्चित वर्णों के बाद या जब कोई नई लाइन भेजी जाती है।

मुझे पता चला है कि एक ही स्ट्रीम या फ़ाइल लिखने वाले कई धागे अधिकतर ठीक हैं - यह देखते हुए कि आउटपुट परमाणु रूप से संभवतः किया जाता है। यह ऐसा कुछ नहीं है जिसे मैं उत्पादन वातावरण में अनुशंसा करता हूं, हालांकि यह बहुत अप्रत्याशित है।

3

यह व्यवहार सीओटी स्ट्रीम के ओएस विशिष्ट कार्यान्वयन पर निर्भर करता है। मुझे लगता है कि कोउट पर लिखने के संचालन आपके मामले में मध्यवर्ती रूप से कुछ थ्रेड विशिष्ट मेमोरी में buffered हैं, और फ्लश() ऑपरेशन उन्हें कंसोल पर मुद्रित करने के लिए मजबूर करता है। मुझे लगता है, चूंकि एंडल में फ़्लश() ऑपरेशन को कॉल करना शामिल है और आपके मुख्य फ़ंक्शन में एंडल को थ्रेड के बाद भी आपके परिवर्तन दिखाई नहीं देते हैं।

बीटीडब्ल्यू आउटपुट को थ्रेड के बीच साझा ओस्ट्रीम में सिंक्रनाइज़ करना एक अच्छा विचार होगा, अन्यथा आप उन्हें अंतःस्थापित कर सकते हैं। हम अपने लॉगिंग वर्गों के लिए ऐसा करते हैं जो लॉगिंग संदेशों को संबंधित ओस्ट्रीम में लिखने के लिए पृष्ठभूमि थ्रेड का उपयोग करते हैं।

+0

मुझे यह जानकर आश्चर्य होगा कि प्रति प्रक्रिया एक से अधिक स्टडआउट बफर लागू करने के लिए मानक, आदि द्वारा अनुमत है लेकिन यह एकमात्र संभावित स्पष्टीकरण की तरह प्रतीत होता है। बेशक, केवल ओपी ने इसे देखा है o_O – delicateLatticeworkFever

+0

@goldilocks: हाँ सहमत हैं, वर्णित व्यवहार मुझे भी आश्चर्यचकित करता है! लेकिन यह ओएस विशिष्ट हो सकता है जो भी cout/stdout बफर कार्यान्वयन से परे है, है ना? यह जानना दिलचस्प होगा कि ओपी द्वारा कौन सा ओएस उपयोग किया जाता है ... –

+0

धन्यवाद makulik। आपकी तर्क अच्छी लगती है लेकिन अगर वास्तव में cout के पास एक अलग स्ट्रीम बफर प्रति थ्रेड – Rajat

0

आपके संदेशों की छोटी अवधि को देखते हुए, फ्लश के बिना कुछ भी दिखाई नहीं दे सकता है। (यह न भूलें कि std::endl<< '\n' << std::flush के बराबर है।)

0

मैं के साथ और फ्लश (gcc 4.3.2 boost 1.47 Linux RH5)

मुझे लगता है अपने cygwin प्रणाली संबद्ध std::streambuf के साथ कई std::cout वस्तुओं को लागू करने के लिए चुनता है कि बिना पूछा व्यवहार मिलता है। यह मुझे लगता है कि कार्यान्वयन विशिष्ट है। flush या अंतराल केवल इसके बफर को अपने ओएस नियंत्रित आउटपुट अनुक्रम पर फ्लश करने के लिए बफर करता है क्योंकि आपके थ्रेड के कोउट ऑब्जेक्ट को बफर किया जाता है।

धागे के बीच ostream का संदर्भ साझा करना समस्या को हल करना चाहिए।