7

मैं :: थ्रेड को बढ़ावा देने के लिए काफी नया हूं, मैंने प्रलेखन पढ़ा है और मुझे अभ्यास में इसे लागू करने में कुछ परेशानी हो रही है, शायद आप मदद कर सकते हैं? सबसे पहले, मैं समय एक आत्म निहित कोड सूची व्यवहार है कि मैं अभी तक समझ में नहीं आता के 2 प्रकार दर्शाता है लिखने के लिए ले लिया है ...बढ़ावा :: धागे उदाहरण और ढेर भ्रष्टाचार संदेश

कार्यक्रम उपयोगकर्ता 3 अलग आदेश जारी करने के लिए अनुमति देता है,

  • कार्य [नाम]
  • जानकारी
  • छोड़ने

उद्देश्य है कि कार्य एक नया धागे पर कुछ काम का शुभारंभ करेंगे है, लेकिन फिर काम पूरा होने पर कमांड प्रॉम्प्ट पर वापस लौटें। उपयोगकर्ता जानकारी आदेश दे सकता है कि यह पता लगाने के लिए कि कौन से कार्य पूरे हुए हैं और जो नहीं हैं।

मैं दोहरी कोर विन 7 मशीन और विजुअल स्टूडियो 2008 एक्सप्रेस का उपयोग कर रहा हूं।

समस्या 1>

आदेश जारी करने वाले, कार्य p1 p2 p3, चल 3 कार्य शुरू होता है। इसे जानकारी जारी करके चेक किया जा सकता है। कुछ सेकंड के बाद काम पूरा हो गया है, हालांकि किसी कारण से पूरा ध्वज हमेशा कार्यों के 1 या 2 पर सही नहीं होता है।

विंडोज example.exe में एक ब्रेकपाइंट ट्रिगर किया है:

समस्या 2>

कार्यक्रम quiting तो निम्न संदेश पैदा करता है। यह ढेर के भ्रष्टाचार के कारण हो सकता है, जो example.exe में किसी बग को इंगित करता है या किसी भी डीएलएल को लोड किया गया है। यह उपयोगकर्ता को F12 दबाकर भी हो सकता है जबकि example.exe पर ध्यान केंद्रित किया गया है। आउटपुट विंडो में अधिक नैदानिक ​​जानकारी हो सकती है।

उम्मीद है कि आप इस व्यवहार और सहायता को पुन: उत्पन्न कर सकते हैं।

अग्रिम धन्यवाद। एलेक्स।

//WARNING: THIS CODE DOES NOT BEHAVE EXACTLY AS INTENDED 
#include <iostream> 
#include <string> 
#include <sstream> 
#include <boost/thread.hpp> 

using namespace std; 

class task { 
public: 
    string mname; 
    bool completed; 
    void start() 
    { 
     int a = 0; 
     for (int i=0 ; i<10000; i++) 
     { 
      for (int j=0 ; j<100000; j++) 
      { 
       a= i*2; 
      } 
     } 
     this->completed = true; 
    } 
    task(string name) 
    { 
     mname = name; 
     completed = false; 
    } 
}; 

class taskManager{ 
    public: 
     boost::thread_group threads; 
     void startTask(string name) 
     { 
      //add new task to vector list   
      mtasks.push_back(task(name)); 
      // execute start() on a new thread 
      threads.create_thread(boost::bind(&task::start, &mtasks.back())); 
     } 
     int tasksTotal() 
     { 
      return mtasks.size(); 
     } 
     string taskInfo(int i) 
     { 
      string compstr("Not Completed"); 
      if (mtasks[i].completed == true) 
      { 
       compstr = "Completed"; 
      } 
      return mtasks[i].mname + " " + compstr; 
     } 
    private: 
     vector<task> mtasks; 
}; 

int main(int argc, char* argv[]) 
{ 
    string cmd, temp; 
    stringstream os; 
    bool quit = false; 
    taskManager mm; 

    cout << "PROMPT>"; 

    while (quit == false) 
    { 
     //Wait for a valid command from user 
     getline(cin,cmd); 

     // Reset stringstream and assign new cmd string 
     os.clear(); 
     os << ""; 
     os << cmd; 
     //parse input string 
     while (os >> temp) 
     {    
      if (temp.compare("task") == 0) 
      { 
       while (os >> temp) { mm.startTask(temp); }      
      } 
      if (temp.compare("info") == 0) 
      { 
       // Returns a list of all completed and not completed tasks 
       for (int i = 0; i<mm.tasksTotal(); i++) 
       { 
        cout << mm.taskInfo(i).c_str() << endl; 
       }       
      } 
      if (temp.compare("quit") == 0){ quit = true; } 
     } 

     cout << "PROMPT>"; 
    } 

    mm.threads.join_all();  

    return 0; 
}; 

उत्तर

4

taskManager::startTask विधि में अपने कोड के साथ एक समस्या है:

mtasks.push_back(task(name)); 
// execute start() on a new thread 
threads.create_thread(boost::bind(&task::start, &mtasks.back()) 

समस्या है कि यहाँ वापस एक नया कार्य को आगे बढ़ाने पर, अपने वेक्टर कुछ जगह पुनः आवंटित करना पड़ सकता है और इस तरह के अमान्य है आपके पुराने वेक्टर तत्वों के संदर्भ, जैसे taskinfo पर निम्न कॉल गलत तत्वों का संदर्भ लेंगे। जैसे ही आप पुराने तत्वों को हटाते हैं, आपका ढेर किसी भी तरह दूषित हो जाएगा।

एक आसान फिक्स आपके taskManager कक्षा के निर्माता में वेक्टर के लिए कुछ जगह आरक्षित करना होगा, हालांकि आपको इसके बजाय अपने कार्य/कार्य प्रबंधक मॉडल का डिज़ाइन बदलना चाहिए। एक और तरीका std::deque का उपयोग करना होगा, क्योंकि वह स्मृति को पुन: आवंटित नहीं करेगा।

+1

एक 'std :: deque'' std :: vector' की बजाय यहां काम करेगा क्योंकि डेक मौजूदा प्रविष्टियों को पुन: आवंटित नहीं करेगा। –

+0

@ जेम्सस्स्टर हाँ अच्छा विचार, इसे जोड़ा। – inf

+0

मुझे इस तरह से पुरानी प्रविष्टियों को std :: वेक्टर पुन: आवंटित करने का एहसास नहीं हुआ, मुझे विश्वास था कि समस्या मेरे बूस्ट :: थ्रेड लाइब्रेरी उपयोग के साथ थी। – AlexS