2009-02-26 18 views
10

मैं AfxBeginThread का उपयोग करके एक धागा उत्पन्न करता हूं जो कि केवल एक अनंत है जबकि लूप:एमएफसी थ्रेड को कैसे मारें?

UINT CMyClass::ThreadProc(LPVOID param) 
{ 
    while (TRUE) 
    { 
     // do stuff 
    } 
    return 1; 
} 

मैं अपने वर्ग विनाशक में इस धागे को कैसे मारूं?

मुझे लगता है कि

UINT CMyClass::ThreadProc(LPVOID param) 
{ 
    while (m_bKillThread) 
    { 
     // do stuff 
    } 
    return 1; 
} 

जैसे कुछ और फिर विनाशक में m_bKillThread से FALSE सेट करें। लेकिन मुझे अभी भी विनाशक में इंतजार करने की ज़रूरत है जब तक धागा मर जाए।

उत्तर

19

सक्रिय धागा की हत्या:

धागा हैंडल (m_hThread) प्राप्त करने के लिए AfxBeginThread (CWinThread*) की वापसी मान का उपयोग करें तो पारित कि TerminateThread Win32 एपीआई को संभाल। यद्यपि धागे को समाप्त करने का यह एक सुरक्षित तरीका नहीं है, इसलिए कृपया पढ़ें।

समाप्त करने के लिए थ्रेड के लिए प्रतीक्षा कर रहा है:

उपयोग AfxBeginThread (CWinThread*) के रिटर्न मान, सदस्य m_hThread पाने के लिए तो यह समारोह WAIT_OBJECT_0 देता है, तो उसके बाद धागा समाप्त हो गया है WaitForSingleObject(p->m_hThread, INFINITE); का उपयोग करें। INFINITE के बजाय आप टाइमआउट होने से पहले प्रतीक्षा करने के लिए मिलीसेकंड की संख्या भी डाल सकते हैं। इस मामले में WAIT_TIMEOUT वापस कर दिया जाएगा। कि धागा बाहर निकलने चाहिए ध्वज के WaitForSingleObject बस किसी तरह का सेट करने से पहले

:

अपने धागा है कि यह खत्म होना चाहिए करने के लिए संकेतन। फिर धागे के अपने मुख्य पाश में आप उस बूल वैल्यू की जांच करेंगे और अनंत लूप को तोड़ देंगे। अपने विनाशक में आप इस ध्वज को सेट करेंगे तो WaitForSingleObject करें।

और भी बेहतर तरीके:

यदि आप और नियंत्रण आप boost conditions की तरह कुछ का उपयोग कर सकते की जरूरत है।

1

आपको प्रतीक्षा करनी चाहिए, जब तक कि थ्रेड सभी चीजें न करें।

if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_OBJECT_0) 
    ;//all right 
else 
    ;//report error 

टर्मिनेट थ्रेड फ़ंक्शन का उपयोग करके सावधान रहें, यह बहुत खतरनाक है।

4

बीटीडब्ल्यू, टर्मिनेट थ्रेड() के बारे में, इस तरह इसका उपयोग करें।

DWORD exit_code= NULL; 
if (thread != NULL) 
{ 
    GetExitCodeThread(thread->m_hThread, &exit_code); 
    if(exit_code == STILL_ACTIVE) 
    { 
     ::TerminateThread(thread->m_hThread, 0); 
     CloseHandle(thread->m_hThread); 
    } 
    thread->m_hThread = NULL; 
    thread = NULL; 
} 
1

सबसे पहले आप एक तरह से धागा शुरू करने के लिए जब यह finished है, तो MFC धागा वस्तु को नहीं हटाता है, MFC धागा के लिए डिफ़ॉल्ट सेटिंग में ही नष्ट करने के लिए ताकि आप उस बंद करने के लिए चाहते हैं।

m_thread = AfxBeginThread(ThreadProc, this, THREAD_PRIORITY_NORMAL ,CREATE_SUSPENDED); 
    m_thread->m_bAutoDelete = FALSE; 
    m_thread->ResumeThread(); 

अब धागे में, आप एक तंत्र चाहते हैं कि कॉलर थ्रेड इसे स्वयं समाप्त करने के लिए एक संकेत भेज सके। कई तरीकों से हैं, सिग्नल की स्थिति की जांच करने के लिए WaitForSingleObject है या किसी अन्य तरीके से यह थ्रेड केवल एक संदेश भेजने के लिए है। यह बल्कि इसे मारने के लिए सुंदर अंत है।

जबकि यह धागा स्वयं समाप्त हो रहा है (= थ्रेड फ़ंक्शन से बाहर निकलना, सफाई करना), आप मुख्य धागे को बाहर निकलने से पहले इसे पूरा करने के लिए प्रतीक्षा कर सकते हैं।

 int wait = 2000 // seconds (I am waiting for 2 seconds for worker to finish) 
    int dwRes = WaitForSingleObject(m_thread->m_hThread, wait); 
    switch (dwRes) 
    { 
    case WAIT_OBJECT_0: 
     TRACE(_T("worker thread just finished")); break; 
    case WAIT_TIMEOUT: 
     TRACE(_T("timed out, worker thread is still busy")); break; 
    } 

नोट की स्थापना m_bAutoDelete = FALSE ऊपर बना यह संभव हम अभी भी एक वैध संभाल जब धागा खत्म तो हम उस पर इंतजार कर सकते हैं। आखिरी चीज जो आप करना चाहते हैं वह अपनी स्मृति को मुक्त करने के लिए CWinThread ऑब्जेक्ट को हटा देती है (क्योंकि हमने ऐसा करने की ज़िम्मेदारी ली है)।

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