6

मैं एकाधिक सर्वरों पर डेटा भेजने और प्राप्त करने के लिए एक तंत्र बना रहा हूं। सर्वर विंडोज पर चलाए जाते हैं और डेल्फी 7 का उपयोग किया जाता है।डेल्फी मल्टीथ्रेडिंग में 100% सीपीयू से कैसे बचें?

डेटा भेजना कई साथ-साथ धागे में बनाया गया है और यह जानना संभव नहीं है कि कौन सा धागा डेटा पहले बनाएगा। बफर में डेटा जोड़ने का क्षण क्रिटिकलसेक्शन द्वारा सिंक्रनाइज़ किया जाता है। प्रेषण धागे लगातार जांच कर रहे हैं कि भेजने के लिए कोई नया डेटा है या नहीं। ऐसा करने से प्रत्येक थ्रेड 1 सीपीयू कोर खाता है। यह बहुत तेज़ काम करता है, लेकिन जब सर्वर डेटा नहीं भेज रहा है तब भी सीपीयू लगभग 100% है। मुझे कई धागे से अधिक की जरूरत है और मुझे इस उच्च CPU उपयोग से बचने की जरूरत है।

मैं दो विकल्प की कोशिश की है:

  1. नींद - अगर वहाँ बफर में कोई डाटा नहीं है मैं नींद चलाने (1)। सीपीयू कोर लोड नहीं होता है, लेकिन नए डेटा पर प्रतिक्रिया करने की गति लगभग 100 गुना कम है। यह एक समाधान नहीं है।

  2. धागे को मारना और बनाना। यदि बफर में कोई डेटा नहीं है तो मैं धागे को मारता हूं। जो डेटा जोड़ता है वह एक नया धागा बना देगा। नया धागा डेटा भेज देगा, बफर को मुक्त करेगा और फिर से मारा जाएगा। सीपीयू लोड कम हो गया है लेकिन बनाने और मारने में बहुत अधिक समय लगता है। नतीजतन गति 100 गुना कम है।

क्या सोने का कोई विकल्प है (1) जो 100% सीपीयू का उपभोग नहीं कर रहा है और तेजी से प्रतिक्रिया करता है? या कुछ घटना होने से पहले धागे को रोकना संभव है?

प्रश्न का उत्तर दिया गया है। यह मेरे लिए काम करता है https://stackoverflow.com/a/4401519/4052208

+1

देखें इस: http: // stackoverflow। कॉम/प्रश्न/4401171/स्वयं निलंबन-ए-थ्रेड-इन-डेल्फी-जब-इसकी आवश्यकता नहीं है और सुरक्षित रूप से फिर से शुरू हो रहा है –

+2

क्या आपने OmniThreadLibrary - http://otl.17slon.com/ का उपयोग करने का प्रयास किया है? – RBA

+5

अपने धागे की जांच न करें - काम जोड़ने पर उन्हें सूचित करें। थ्रेड सिंक्रनाइज़ेशन ऑब्जेक्ट्स जैसे 'टीवेन्ट' पर इंतजार कर सकते हैं - जब कतार में काम जोड़ा जाता है तो आप एक उपलब्ध धागे को पकड़ सकते हैं और इसे काम शुरू करने के लिए संकेत दे सकते हैं। ओटीएल जैसे पुस्तकालय इस प्रकार की चीज को लागू करते हैं यदि आपको व्हील का पुन: आविष्कार करने के लिए पर्याप्त कुछ भी नहीं चाहिए। –

उत्तर

9

आप थ्रेड को WaitFor* फ़ंक्शंस वाले डेटा के लिए प्रतीक्षा करने दे सकते हैं। वे प्रोसेसर संसाधन नहीं खाएंगे।

मैं WaitForMultipleOjects का उपयोग करने की अनुशंसा करता हूं, जिसमें कुछ घटनाओं का इंतजार करने की संभावना है। उदाहरण के लिए, मुख्य समारोह डेटा निर्माता द्वारा स्थापित किया जाना चाहिए (के लिए CreateEvent या डेल्फी आवरण वर्ग TEvent देखो) जब डेटा बफर में है, और एक अन्य घटना धागा समाप्ति के लिए कार्य करता है:

//Execute body 
repeat 
    WaitRes := WaitForMultipleObjects(2, @FEventHandles, False, CONST_TIMEOUT); // or INFINITE 
    if WaitRes = WAIT_OBJECT_0 + 1 then // event from data producer 
    GetDataFromBuffer(); 

until WaitRes = WAIT_OBJECT_0; // external event for thread stop 
संबंधित मुद्दे