2009-09-29 17 views
6

में आपके धागे की प्रोग्राम संख्या कैसे करें, मैंने इसे आज डॉ। डॉब्स साइट पर http://www.ddj.com/hpc-high-performance-computing/220300055?pgno=3 पर पाया है यह थ्रेड इम्प्लामेंटेशन के बारे में एक अच्छा सुझाव है। डेल्फी में टीटीएचड के साथ इसे प्राप्त करने का सबसे अच्छा तरीका क्या है मुझे आश्चर्य है? धन्यवाद ब्रायनडेल्फी

डॉ डोब्स ============== से

===

मेक विन्यास multithreading! किसी प्रोग्राम में प्रयुक्त थ्रेड की संख्या हमेशा मनमानी संख्या में 0 (कोई अतिरिक्त धागे नहीं) से कॉन्फ़िगर करने योग्य होनी चाहिए। यह न केवल इष्टतम प्रदर्शन के लिए अनुकूलन की अनुमति देता है, बल्कि यह क्लाइंट सिस्टम पर अज्ञात दौड़ की स्थिति होने पर भी एक अच्छा डिबगिंग टूल और कभी-कभी जीवनभर वाला साबित होता है। मुझे एक से अधिक परिस्थितियों को याद है जहां ग्राहक मल्टीथ्रेडिंग को बंद करके घातक कीड़े को दूर करने में सक्षम थे। यह निश्चित रूप से केवल multithreaded फ़ाइल I/O पर लागू नहीं होता है।

निम्नलिखित स्यूडोकोड पर विचार करें:

int CMyThreadManger::AddThread(CThreadObj theTask) 
{ 
    if(mUsedThreadCount >= gConfiguration.MaxThreadCount()) 
     return theTask.Execute(); // execute task in main thread 
    // add task to thread pool and start the thread 
    ... 
} 

इस तरह के एक तंत्र बहुत जटिल नहीं है (हालांकि थोड़ा और अधिक काम शायद यहाँ दिखाया गया है की तुलना में इसकी आवश्यकता होगी), लेकिन यह कभी कभी बहुत प्रभावी है। इसका उपयोग ओपनएमपी या इंटेल के थ्रेडेड बिल्डिंग ब्लॉक जैसे प्रीबिल्ट थ्रेडिंग लाइब्रेरीज़ के साथ भी किया जा सकता है। यहां दिखाए गए मापों को ध्यान में रखते हुए, एक से अधिक कॉन्फ़िगर करने योग्य थ्रेड गिनती शामिल करना एक अच्छा विचार है (उदाहरण के लिए, फ़ाइल I/O के लिए एक और कोर CPU कार्यों के लिए एक)। डिफ़ॉल्ट रूप से फ़ाइल I/O और < के लिए डिफ़ॉल्ट 0 हो सकता है CPU के कार्यों के लिए > प्राप्त कोरों की संख्या। लेकिन सभी multithreading अलग करने योग्य होना चाहिए। एक अधिक परिष्कृत दृष्टिकोण में मल्टीथ्रेड किए गए प्रदर्शन का परीक्षण करने के लिए कुछ कोड भी शामिल हो सकते हैं और स्वचालित रूप से उपयोग किए गए धागे की संख्या निर्धारित कर सकते हैं, अलग-अलग कार्यों के लिए भी अलग-अलग हो सकते हैं।

===================

उत्तर

0

मैं आम तौर पर है सिर्फ एक ही वर्ग TThread, एक है कि एक कतार या स्टैक से 'कार्यकर्ता आइटम' लेता से इनहेरिट, और जब कोई और आइटम उपलब्ध न हो तो उन्हें निलंबित कर दें। मुख्य कार्यक्रम तब तय कर सकता है कि इस थ्रेड के कितने उदाहरण तत्काल और शुरू करने के लिए हैं। (इस कॉन्फ़िगरेशन मान का उपयोग कर)।

यह 'कार्यकर्ता आइटम कतार' जरूरत पड़ने पर भी बहुत चालाक निलंबित धागे बढ़ाएं या नया धागा बनाने के लिए किया जाना चाहिए (और जब सीमा यह परमिट), जब एक कार्यकर्ता मद पंक्ति या है एक धागा एक कार्यकर्ता आइटम की प्रक्रिया पूरी होने ।

+5

धागे को निलंबित और फिर से शुरू करने की कोई आवश्यकता नहीं है। प्रत्येक थ्रेड को किसी ईवेंट या सेमफोर पर प्रतीक्षा करें, या थ्रेड मैसेज लूप के साथ 'WaitMessage() 'का उपयोग करें (ओएलई के लिए आवश्यक हो सकता है)। यहां [डेल्फी] के तहत SO पर विषय के बारे में बहुत सी चर्चा है, इसे पढ़ें, लेकिन लोगों के तर्कों को अनदेखा करना सबसे अच्छा है जो सोचते हैं कि वे एम्बरकाडेरो और माइक्रोसॉफ्ट देवताओं से बेहतर जानते हैं, और आपको 'सस्पेंड() ' और 'फिर से शुरू करें) ठीक होगा। – mghie

5

मैं एक अमूर्त वर्ग टीटीस्क बनाउंगा। यह वर्ग कार्य निष्पादित करने के लिए है। विधि के साथ निष्पादित करें:

type 

    TTask = abstract class 
    protected 
    procedure DoExecute; virtual; abstract; 
    public 
    procedure Execute; 
    end; 

    TTaskThread = class (TThread) 
    private 
    FTask : TTask; 
    public 
    constructor Create(const ATask: TTask); 
    // Assigns FTask and enables thread, free on terminate. 

    procedure Execute; override; // Calls FTask.Execute. 
end; 

विधि चेकों निष्पादित थ्रेड की संख्या। यदि अधिकतम नहीं पहुंचता है, तो यह TTaskThread का उपयोग करके थ्रेड शुरू करता है जो DoExecute को कॉल करता है और इस तरह कार्य को थ्रेड में निष्पादित करता है। यदि अधिकतम पहुंच गया है, तो DoExecute को सीधे कहा जाता है।

4

The answer by Gamecat जहां तक ​​सार कार्य वर्ग का संबंध है, अच्छा है, लेकिन मुझे लगता है कि कॉलिंग थ्रेड में एक कार्य के लिए DoExecute() पर कॉल करना (जैसा लेख भी स्वयं करता है) एक बुरा विचार है। मैं हमेशा पृष्ठभूमि थ्रेड द्वारा निष्पादित कार्यों को कतारबद्ध करता हूं, जब तक कि थ्रेडिंग पूरी तरह अक्षम नहीं हो जाती, और यहां क्यों है।

, निम्नलिखित (काल्पनिक) मामले पर विचार करें जहां तीन स्वतंत्र सीपीयू बाध्य प्रक्रियाओं पर अमल करने की जरूरत है:

Procedure1_WhichTakes200ms; 
Procedure2_WhichTakes400ms; 
Procedure3_WhichTakes200ms; 

अपने डुअल कोर प्रणाली के बेहतर उपयोग के लिए आप उन्हें दो धागे में निष्पादित करने के लिए चाहते हैं। आप पृष्ठभूमि धागे की संख्या को एक तक सीमित कर देंगे, इसलिए मुख्य धागे के साथ आपके पास कोर के रूप में कई धागे हैं।

अब पहली प्रक्रिया एक कार्यकर्ता धागे में निष्पादित की जाएगी, और यह 200 मिलीसेकंड के बाद खत्म हो जाएगी। दूसरी प्रक्रिया तुरंत शुरू हो जाएगी और मुख्य धागे में निष्पादित की जाएगी, क्योंकि एकल कॉन्फ़िगर किए गए कार्यकर्ता थ्रेड पहले से ही कब्जा कर लिया गया है, और यह 400 मिलीसेकंड के बाद समाप्त हो जाएगा। फिर अंतिम प्रक्रिया कार्यकर्ता धागे में निष्पादित की जाएगी, जो अब 200 मिलीसेकंड के लिए पहले से सो रही है, और 200 मिलीसेकंड के बाद खत्म हो जाएगी। कुल निष्पादन समय 600 मिलीसेकंड, और उस समय के 2/3 के लिए केवल दोनों धागे में से एक वास्तव में सार्थक काम कर रहा था।

आप प्रक्रियाओं (कार्यों) को फिर से व्यवस्थित कर सकते हैं, लेकिन वास्तविक जीवन में यह जानना संभवतः पहले से ही असंभव है कि प्रत्येक कार्य कितना समय लगेगा।

अब थ्रेड पूल को नियोजित करने का सामान्य तरीका मानें। कॉन्फ़िगरेशन के अनुसार आप पूल में धागे की संख्या को 2 (कोर की संख्या) तक सीमित कर देंगे, केवल थ्रेड को पूल में शेड्यूल करने के लिए मुख्य थ्रेड का उपयोग करें, और उसके बाद सभी कार्यों को पूरा करने की प्रतीक्षा करें। कतारबद्ध कार्यों के उपरोक्त क्रम के साथ थ्रेड 1 पहला कार्य करेगा, थ्रेड दो दूसरा कार्य करेगा। 200 मिलीसेकंड के बाद पहला कार्य पूरा हो जाएगा, और पहला कार्यकर्ता थ्रेड पूल से तीसरा कार्य करेगा, जो बाद में खाली होगा। 400 मिलीसेकंड के बाद दूसरा और तीसरा कार्य पूरा हो जाएगा, और मुख्य धागा को अनब्लॉक कर दिया जाएगा। 400 मिलीसेकंड निष्पादन के लिए कुल समय, उस समय दोनों कोरों पर 100% भार के साथ।

कम से कम सीपीयू-बाउंड धागे के लिए ओएस शेड्यूलर के लिए कतारबद्ध काम करने के लिए महत्वपूर्ण महत्व है। मुख्य धागे में DoExecute() को कॉल करना उसमें हस्तक्षेप करता है, और नहीं किया जाना चाहिए।

0

यदि आप एक नज़र (http://www.csinnovations.com/framework_overview.htm) देखना चाहते हैं, तो मेरा ढांचा कॉन्फ़िगरेशन फ़ाइल में किसी भी थ्रेड के लिए थ्रेड पूल गिनती की अनुमति देता है।