2009-11-04 8 views
8

मुझे यकीन नहीं है कि कौन सी रणनीति अपनाने के लिए है ... मैं अपने ऑपरेशन को पूरा करने पर ध्यान केंद्रित कर रहा हूं, लेकिन मैं प्रदर्शन समस्याओं को भी एक मिनट में रखना चाहता हूं। .. निष्पादित एक विधि है() जिसे एक ऑपरेशन पूरा होने तक प्रतीक्षा (सिंक्रनाइज़ेशन चलाएं) है। यह ऑपरेशन एक और धागे पर होता है। वहाँ एक ही बात लागू करने के लिए 2 तरीके ...मैनुअल रीसेट इवेंट या थ्रेड के बीच एक विकल्प बनाने के लिए। नींद()

ManualResetEvent

void Execute() 
{ 
    taskHandle = new ManualResetEvent(false); 
    . 
    . 
    //delegate task to another thread 
    . 
    . 
    taskHandle.WaitOne(); 
} 

या

का उपयोग कर एक सरल का उपयोग करके तक जबकि

void Execute() 
{ 
    . 
    . 
    //delegate task to another thread 
    . 
    . 
    while (!JobCompleted) 
     Thread.Sleep(1000); 
} 

कौन से दो तरीकों में से एक का निर्माण कर रहे हैं क्या मुझे अपनाना चाहिए ... क्यों?

संपादित करें:

प्रश्न 2। अगर मैं सिर्फ खाली था तो क्या होगा? क्या फर्क पड़ता है...?

while(!JobCompleted); 

संपादित करें: (कुछ मैंने पहले इकट्ठा)

http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml - यह लेख का कहना है manualresets अपेक्षाकृत धीमी है क्योंकि वे में प्रबंधित कोड से बाहर जाने के लिए और वापस आ रहे हैं ...

+0

बस थ्रेड को इंगित करना चाहते हैं। नींद (0) उपयोग। इंगित करने के लिए शून्य (0) निर्दिष्ट करें कि यह थ्रेड अन्य प्रतीक्षा धागे को निष्पादित करने की अनुमति देने के लिए निलंबित किया जाना चाहिए। इस मामले में नींद (0) नींद (1000) से बेहतर है, लेकिन वेटहैंडल का उपयोग करना अभी भी अधिक उपयुक्त है। –

+4

खाली जबकि लूप मूल रूप से एक स्पिनवाइट है - यह पूरी तरह से एक सीपीयू का उपभोग करेगा। सिफारिश नहीं की गई। – nitzmahone

उत्तर

13

जिज्ञासा से, ManualResetEvent और AutoResetEvent क्यों नहीं? किसी भी तरह से, नींद-जांच-नींद दृष्टिकोण पर ओएस आदिम के साथ जाएं।

तुम भी एक Monitor ताला (या तो Monitor.Enter और Monitor.Exit, या एक lock ब्लॉक के माध्यम से के माध्यम से स्पष्ट रूप से) इस्तेमाल कर सकते हैं, लेकिन दृष्टिकोण आप वास्तव में क्या कर रहे हैं पर आधारित होना चाहिए; यदि यह एक परिदृश्य है "इनमें से केवल चीजें हैं और मुझे विशेष पहुंच की आवश्यकता है", तो Monitor लॉक का उपयोग करें। यदि यह है "मुझे तक प्रतीक्षा करने की आवश्यकता है, अन्य थ्रेड संसाधन पहुंच के अलावा अन्य कारणों से समाप्त करता है", फिर AutoResetEvent या ManualResetEvent का उपयोग करें।

सुझावों का उपयोग करने के लिए Thread.Join अच्छा कर रहे हैं (और केवल यदि)

  1. आप अन्य Thread वस्तु
  2. की पहुंच है जब तक अन्य धागा समाप्त हो जाता है निष्पादित करने के लिए नहीं करना चाहती।

यदि दोनों में से सही नहीं है (यदि आप पहुँच नहीं है, या अन्य धागा समाप्त नहीं होगा, यह सिर्फ एक "सभी स्पष्ट" संकेत देंगे) तो Thread.Join व्यवहार्य नहीं है।

सबसे खराब विकल्प

while(!JobCompleted);

कि उन दोनों के बीच में किसी भी विराम के बिना चर का अनावश्यक चेक के प्रोसेसर बाँध जाएगा है। हां, यह ऑपरेशन पूरा होने तक आपके धागे को अवरुद्ध कर देगा, लेकिन आप अधिकतम CPU उपयोग (या कम से कम एक कोर के लायक) करेंगे।

+0

कुछ भी पढ़ें मैनुअल रीसेट कर्नेल मोड में काम करता है ... यदि ऐसा है तो प्रदर्शन प्रदर्शन ओवरहेड होना चाहिए, है ना? पीएस: मैंने फिर से प्रश्न संपादित किया है ... – deostroll

+0

आप ओएस आदिम के साथ जाने का सुझाव देते हैं, लेकिन आपको वास्तव में क्यों समझाया जाना चाहिए। – Gigi

2

आप तक पहुंच नहीं है मूल थ्रेड ऑब्जेक्ट, या वह एक्सेस प्राप्त कर सकते हैं, आप Thread.Join() का उपयोग करके सबसे अच्छे हैं।

संपादित करें: इसके अलावा, अगर इस WinForms या WPF की तरह एक जीयूआई में हो रही है, तो आप BackgroundWorker

+0

मुझे थ्रेड ऑब्जेक्ट तक पहुंच नहीं है ... – deostroll

+0

फिर मैन्युअल रीसेट इवेंट का उपयोग @nitzmahone के रूप में करता है। या उस थ्रेड को पाने का एक तरीका खोजें। मैन्युअल रीसेट इवेंट का उपयोग करने में एकमात्र कमी यह है कि कॉलर और कार्यकर्ता दोनों को इसका उपयोग करना होगा, संभवतः अवांछित निर्भरता बनाना। – Randolpho

+0

@ रैंडोल्फो। एक दूसरे को सिग्नल करने में सक्षम होने के लिए दोनों विधियों को संसाधन साझा करना नहीं होगा? जबकि लूप के मामले में दोनों धागे को 'जॉब कॉम्प्लेटेड' बूलियन के बारे में जानना होगा। – rocka

4

का उपयोग कर घटना processors- आप को जगाने के लिए होने नहीं कर रहे हैं के अधिक कुशल उपयोग करता है पर विचार कर सकते मतदान के लिए पैरेंट धागा। ईवेंट आग लगने पर कर्नेल आपको जगाएगा।

+0

लेकिन अन्य निर्माण की तुलना में मैन्युअल रीसेटेट्स महंगा नहीं हैं। मैं .NET 2.0 का उपयोग करता हूं। कहीं भी मैन्युअल रीसेट कर्नेल मोड में काम करता है जहां इसकी मॉनीटर विकल्प उपयोगकर्ता मोड में काम करते हैं ... तो अतिरिक्त ओवरहेड मोड के कारण परिवर्तन ...! क्या ये सच है? – deostroll

+0

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

2

Thread.Sleep() का उपयोग करने का मुख्य नुकसान यह है कि आप निर्णय ले रहे हैं कि थ्रेड कितनी देर तक इंतजार करेगा। जिस ऑपरेशन के लिए आप प्रतीक्षा कर रहे हैं वह अधिक या कम समय ले सकता है, और सामान्य रूप से, उस समय सटीक मात्रा को मापना बहुत मुश्किल है। यदि धागा बहुत लंबा सोता है, तो आप सिस्टम संसाधनों का सबसे अच्छा उपयोग नहीं कर रहे हैं।

इष्टतम होने के लिए, आपको ManualResetEvent (या AutoResetEvent) का उपयोग करना चाहिए ताकि जैसे ही निर्भर ऑपरेशन समाप्त हो जाए, आपका धागा फिर से शुरू हो जाए।

0

दोनों दृष्टिकोण मूल रूप से एक ही काम करते हैं। हालांकि लूप थोड़ा और स्पष्ट है, क्योंकि आप नींद का समय निर्दिष्ट कर सकते हैं। हालांकि मैं XXXResetEvent कक्षाओं का उपयोग करता हूं जिसका उपयोग आपके परिदृश्य में परिदृश्य में किया जाना है। मुझे लगता है कि थ्रेडिंग कक्षाओं को अब या बाद में अधिक मजबूत थ्रेडिंग कोड के साथ लागू किया जाएगा ताकि बहु कोर प्रोसेसर पर थ्रेड एफ़िनिटी हो सके।

+0

एक मैन्युअल रीसेट समय आवधिक मतदान से काफी अलग व्यवहार करता है। –

1

मैनुअल रीसेट इवेंट निश्चित रूप से जाने का तरीका है।

आपके द्वारा प्रदान किए गए कोड स्निपेट से, ऐसा लगता है कि आप अपने निष्पादन विधि के भीतर निष्पादन का प्रतिनिधि हैं। यदि यह मामला है, और आप केवल एक ही कार्य का प्रतिनिधि हैं, तो आप प्रतिक्रिया के लिए इंतजार कर रहे हैं तो आप किसी अन्य धागे पर क्यों प्रतिनिधि हैं? आप प्रक्रिया को समकालिक रूप से निष्पादित भी कर सकते हैं।

1

manualresets अपेक्षाकृत धीमी है क्योंकि वे प्रबंधित कोड से बाहर जाने के लिए और में वापस आ रहे हैं ..

वे शायद एक Wait/Pulse combo कहना है, जिसे आप मेरी राय में यहाँ का उपयोग करना चाहिए की तुलना में धीमी है। लेकिन Manual/AutoResetEvents किसी भी Thread.Sleep(x) की तुलना में तेज़ होगा, भले ही आप x = 1 चुनते हैं। और यहां तक ​​कि यदि आप विंडोज टाइमर रिज़ॉल्यूशन को 1ms तक कम करते हैं।

क्या होगा अगर मेरे पास संरचना के दौरान अभी खाली हो? क्या फर्क पड़ता है...?

फिर एक कोर 100% पर घूमता रहेगा जब तक हालत सही बदल जाता है, दूर अन्य धागे कि बजाय इसका इस्तेमाल कर सकते हैं, थोड़ा उपयोगी "एंग्री बर्ड्स" के लिए फ्रेम की गणना की तरह से समय चोरी - या CPU बस सकता है थोड़ा आगे ठंडा, कुछ और नैनोसेकंद के लिए ग्लोबल वार्मिंग के गंभीर प्रभाव में देरी।

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