2010-03-08 12 views
5

मैं अपने आवेदन में एकाधिक (थ्रेड) लूप का उपयोग कर कई थ्रेड का उपयोग कर रहा हूं और अब मैं लूप से बाहर निकलना चाहता हूं जब सभी सक्रिय धागे अपना काम पूरा करते हैं।आप कैसे निर्धारित करते हैं कि बाल धागे

+0

नहीं पूरी तरह से इस सवाल और जवाब से भिन्न: http://stackoverflow.com/questions/435668/code-for-a-simple-thread-pool -इन-सी – xcud

+0

आपका लूप कैसा है? क्या आप धागे बनाने के लिए इसका इस्तेमाल कर रहे हैं? या क्या आप इसे पूरा करने के लिए धागे पर इंतजार करने के लिए इसका उपयोग कर रहे हैं? – ata

उत्तर

1

आप Process.GetCurrentProcess() का उपयोग कर सकते हैं। Threads.Count।

+0

समाधान प्रक्रिया। GetCurrentProcess()। Threads.Count काम नहीं करता है। यह सभी प्रक्रियाओं को चल रहा है लेकिन मुझे अपने आवेदन में चल रहे धागे की गिनती की आवश्यकता है। –

+0

Process.GetCurrentProcess()। Threads.Count वास्तव में वर्तमान प्रक्रिया के लिए थ्रेड की संख्या वापस कर देता है, अगर आपको अपने आवेदन में लूप विचार प्रक्रियाओं के लिए आवश्यक सभी प्रक्रियाओं के सभी धागे को गिनने की आवश्यकता है – Anonymous

+0

इसमें थ्रेड पूल थ्रेड भी शामिल होंगे। यद्यपि आप धागे बनाने से पहले गिनती प्राप्त कर सकते हैं, लेकिन यह अभी भी गारंटी नहीं देगा कि गिनती घटने पर आपके कस्टम थ्रेड समाप्त हो जाते हैं। – ata

1

यहां कई दृष्टिकोण हैं, लेकिन संभवतः उनमें से अधिकतर कुछ करने के लिए निष्पादित धागे को बदलने के लिए नीचे आते हैं (सफलता या अपवाद के माध्यम से, जिसे आप वैसे भी नहीं करना चाहते हैं)। काउंटर को कम करने के लिए Interlock.Decrement का उपयोग करने के लिए एक सरल दृष्टिकोण हो सकता है - और यदि यह शून्य है (या -व, जो शायद एक त्रुटि का मतलब है) ManualResetEvent या Monitor.Pulse किसी ऑब्जेक्ट को छोड़ दें; किसी भी मामले में, मूल धागा उस ऑब्जेक्ट पर प्रतीक्षा करेगा। इस तरह के कई दृष्टिकोण discussed here हैं।

बेशक, 4.0 में टीपीएल बिट्स को देखना आसान हो सकता है, जो यहां बहुत सारे नए विकल्प प्रदान करता है (कम से कम चीजें जैसे Parallel.For PLINQ में)।

यदि आप सिंक्रनाइज़ किए गए कार्य कतार का उपयोग कर रहे हैं, तो यह कतार को बंद करने (नाली) को सेट करना भी संभव हो सकता है, और बस कतार खाली होने की प्रतीक्षा करें? धारणा यहाँ जा रहा है कि अपने कार्यकर्ता धागे की तरह कुछ कर रहे हैं:

जिस स्थिति में
T workItem; 
while(queue.TryDequeue(out workItem)) { // this may block until either something 
    ProcessWorkItem(workItem);   // todo, or the queue is terminated 
} 
// queue has closed - exit the thread 

, एक बार कतार खाली है अपने सभी कार्यकर्ता धागे पहले से ही आत्महत्या करने की प्रक्रिया में किया जाना चाहिए।

5

मान लीजिए कि आपके पास धागे की एक सूची है, यहां दो दृष्टिकोण हैं।

समाधान पहले:

एक समयावधि पैरामीटर के साथ उपयोग Thread.Join() बदले में प्रत्येक थ्रेड के साथ एक समय होनेवाला बनाना। वापसी मूल्य आपको बताता है कि धागा समाप्त हो गया है या नहीं।

समाधान दूसरा:

चेक Thread.IsAlive() अगर धागा अभी भी चल रहा है देखने के लिए।

किसी भी स्थिति में, सुनिश्चित करें कि आपका मुख्य धागा प्रोसेसर समय को चलने वाले धागे में उत्पन्न करता है, अन्यथा आपका प्रतीक्षा लूप अधिकांश/सभी CPU का उपभोग करेगा और आपके कार्यकर्ता धागे को भूखा करेगा।

+0

जुड़ने के मामले में, जॉइन विधि को कॉल करने वाला थ्रेड इसके बदले में प्रतीक्षा करेगा। Thread.IsAlive के मामले में, आपको कुछ निश्चित समय (जैसे 1 सेकंड) मतदान करना होगा। यह जॉइन विधि को कॉल करने जैसा ही होगा, कॉलिंग थ्रेड को सभी थ्रेड समाप्त होने तक प्रतीक्षा करनी होगी। तो बेहतर थ्रेड का उपयोग करें। जॉइन() – ata

+0

मुख्य अंतर यह है कि मतदान IsAlive() आपके मुख्य धागे को अन्य काम करने की अनुमति देता है, यदि कोई है तो। अच्छे अंक हालांकि - यदि कोई काम नहीं किया जाता है, तो शामिल हों() अधिक कुशल विकल्प है। – Bevan

0

आप Thread.Join() का उपयोग कर सकते हैं। Join विधि थ्रेड तक कॉलिंग थ्रेड को अवरुद्ध कर देगा (जिस पर Join विधि कहा जाता है) समाप्त हो जाता है।

तो यदि आपके पास धागे की एक सूची है, तो आप प्रत्येक थ्रेड पर Join के माध्यम से लूप कर सकते हैं और कॉल कर सकते हैं। जब आप सभी धागे मर जाते हैं तो आप लूप केवल बाहर निकल जाएंगे। कुछ इस तरह:

for(int i = 0 ;i < childThreadList.Count; i++) 
{ 
    childThreadList[i].Join(); 
} 
///...The following code will execute when all threads in the list have been terminated.../// 
0

मुझे लगता है कि जॉइन() विधि का उपयोग सबसे साफ तरीका है। मैं अक्सर कई धागे का उपयोग करता हूं, और प्रत्येक धागा आम तौर पर अलग-अलग डेटा स्रोतों (इनफॉर्मिक्स, ओरेकल और एसक्यूएल) से डेटा लोड कर रहा है।) ऊपर वर्णित एक साधारण लूप, प्रत्येक थ्रेड ऑब्जेक्ट (जिसमें मैं स्टोर करता हूं) पर जॉइन() को कॉल करना एक साधारण सूची वस्तु) काम करता है !!!

कार्लोस मेरिघे।

0

मैं धागे की एक HashSet का उपयोग कर पसंद करते हैं:

// create a HashSet of heavy tasks (threads) to run 
HashSet<Thread> Threadlist = new HashSet<Thread>(); 
Threadlist.Add(new Thread(() => SomeHeavyTask1())); 
Threadlist.Add(new Thread(() => SomeHeavyTask2())); 
Threadlist.Add(new Thread(() => SomeHeavyTask3())); 

// start the threads 
foreach (Thread T in Threadlist) 
    T.Start(); 

// these will execute sequential 
NotSoHeavyTask1(); 
NotSoHeavyTask2(); 
NotSoHeavyTask3(); 

// loop through tasks to see if they are still active, and join them to main thread 
foreach (Thread T in Threadlist) 
    if (T.ThreadState == ThreadState.Running) 
    T.Join(); 

// finally this code will execute 
MoreTasksToDo(); 
संबंधित मुद्दे