2012-06-02 19 views
8

मैं जानना चाहता हूं कि डीडब्ल्यूस्क्रिप्ट स्क्रिप्ट के अंदर धागे का उपयोग करने में सक्षम है, क्योंकि कुछ इंजन इसके आंतरिक डेटा संरचनाओं तक पहुंच को सिंक्रनाइज़ नहीं करते हैं।क्या डीडब्ल्यूस्क्रिप्ट थ्रेड-सुरक्षित है?

+0

-1 इस सवाल का दस्तावेज़ीकरण, डीडब्लूस्क्रिप्ट प्रोजेक्ट वेबसाइट, वेब सर्च इत्यादि के सामने वाले पृष्ठ को थोड़ा सा जवाब दिया गया है। प्रश्न पूछने से पहले कुछ प्रयास करें। –

+1

यदि उत्तर ढूंढना आसान है, तो निश्चित रूप से इसे कई बार छोड़ दिया जाना चाहिए, या मैंने सवाल पोस्ट नहीं किया होगा। – FHannes

+4

@ डेविड: अगर हर कोई सिर्फ rtfm होगा, तो कोई स्टैक ओवरफ्लो नहीं होगा :) –

उत्तर

4

अरनॉड महत्वपूर्ण बिंदुओं दिया:

  • प्रत्येक संकलक उदाहरण केवल एक समय में एक धागे से लागू किया जा सकता है। आप एक ही समय में एकाधिक थ्रेड में कई संकलक उदाहरणों को बुला सकते हैं, और एक विशेष कंपाइलर उदाहरण एकाधिक धागे से उपयोग किया जा सकता है, बशर्ते केवल एक धागा इसे एक समय का उपयोग करे।
  • प्रत्येक संकलित प्रोग्राम में कई निष्पादन हो सकते हैं, प्रत्येक निष्पादन अपने स्वयं के धागे में चल रहा है। इसके अलावा कई धागे द्वारा एक विशेष निष्पादन का उपयोग किया जा सकता है, बशर्ते केवल एक धागा इसे एक समय में उपयोग करता हो।
  • प्रत्येक निष्पादन के अपने चर के लिए अपनी जगह होती है, और इसका अपना ढेर होता है, ऑब्जेक्ट इंस्टेंस ढेर पर होते हैं और तकनीकी रूप से निष्पादन में साझा किए जा सकते हैं, इसके लिए कोई लॉकिंग तंत्र नहीं है, लेकिन आप अपना स्वयं का बना सकते हैं।
  • स्क्रिप्ट इंजन किसी भी सिंक्रनाइज़ेशन या लॉकिंग को कक्षाओं या कार्यों का उपयोग करते समय निष्पादित नहीं करता है (इसे TdwsUnit, RTTI, आदि के माध्यम से करें।) है, इसलिए जब धागे में स्क्रिप्ट फांसी चल रहा है, सुनिश्चित करें कि आप केवल उजागर धागे की सुरक्षित सामान (कि RTTI के लिए के बारे में विशेष सावधान रहना होगा, क्योंकि RTL & VCL के बहुत थ्रेड-सुरक्षित के साथ शुरू)

नहीं है एक स्क्रिप्ट के एकाधिक निष्पादन चलाना डेल्फी में कई धागे होने के समान है, हालांकि प्रत्येक नए निष्पादन में न केवल अपना स्वयं का ढेर होता है (डेल्फी धागे की तरह) बल्कि इसकी अपनी परिवर्तनीय जगह भी होती है (डेल्फी में यह थोड़ी सी होगी जैसे आपके पास "थ्रेड var "हर जगह)। और डीडब्ल्यूस्क्रिप्ट निष्पादन को अपने स्वयं के धागे में नहीं होना चाहिए, उन्हें थ्रेडों में स्थानांतरित किया जा सकता है, या कम से कम धागे में इस्तेमाल किया जा सकता है (केवल एक ही सीमा यह है कि प्रत्येक निष्पादन का उपयोग एक समय में केवल एक धागे द्वारा किया जाता है, जैसा कि उपर्युक्त)।

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

"वैश्विक वर्र्स" द्वारा, मेरा मतलब है कि dwsGlobalVarsFunctions.pas में परिभाषित फ़ंक्शंस, जिनका उपयोग इंटर-निष्पादन डेटा एक्सचेंज के लिए किया जा सकता है। उन्हें सक्रिय करने के लिए, बस अपनी परियोजना में "dwsGlobalVarsFunctions का उपयोग करता है"।

वे पढ़ें/WriteGlobalVar काम करता है, जो भंडारण और सभी स्क्रिप्ट एक ही डेल्फी प्रक्रिया के भीतर चल फांसी भर में नामित वेरिएंट को पुन: प्राप्त करने की अनुमति देते का एक सेट का पर्दाफाश, और उन पढ़ता & लेखन को देखने के एक बिंदु से सूत्रण "परमाणु" कर रहे हैं।

+1

एसओ में डीडब्ल्यूएस "भगवान पिता" (या नया पिता) अच्छा है! :) –

+0

जब किसी TdwsProgramExecution ऑब्जेक्ट को थ्रेड में निष्पादित किया जा रहा है, तो क्या कोई अन्य थ्रेड TdwsProgramExecution.EndProgram सुरक्षित रूप से कॉल कर सकता है? – FHannes

+0

नहीं, लेकिन आप इसके लिए स्टॉप कॉल कर सकते हैं (जो कि अगर आप BeginProgram/RunProgram के साथ मैन्युअल रूप से निष्पादित करते हैं तो निष्पादित() द्वारा निष्पादित किया जाता है। इससे स्क्रिप्ट को इसके नियंत्रण में सबसे पुराने अवसर पर रोक दिया जाएगा, यानी। यदि आपकी स्क्रिप्ट डेल्फी फ़ंक्शन चला रही है, तो वह केवल उस फ़ंक्शन से लौटने के बाद ही रुक जाएगी। एंडप्रोग्राम क्लीनअप करता है और इसे निष्पादन थ्रेड से बुलाया जाता है। –

3

डीडब्लूएस दस्तावेज खोलना भी आवश्यक नहीं था। जबकि पुराने codebase सीमा आसपास बनाया गया है,

उदाहरण के लिए, [डीडब्ल्यूएस] अब एक भी संकलित स्क्रिप्ट के कई धागे की सुरक्षित फांसी करने में सक्षम है: :)

बस एक बार देख लेने के at this StackOverflow answer by Eric कि एक संकलित स्क्रिप्ट एक समय में केवल एक धागे द्वारा निष्पादित किया जा सकता है।

संक्षेप में:

  • डीडब्ल्यूएस संकलक थ्रेड-सुरक्षित नहीं है: यदि आप एक धागा भीतर निष्पादन ढेर बनाने के लिए (यदि आप एक संकलक उदाहरण साझा नहीं कर सकते, तो आप एक धागा जरूरत प्रति संकलक उदाहरण);
  • डीडब्लूएस निष्पादन थ्रेड-सुरक्षित है, यदि आप प्रति थ्रेड एक निष्पादन उदाहरण का उपयोग करते हैं: आप कई थ्रेड में एक ही संकलित स्क्रिप्ट चला सकते हैं;
  • धागे के बीच संचार AFAIK उपलब्ध नहीं है, लेकिन यदि आपको सिंक्रनाइज़ेशन की आवश्यकता है तो आप डेल्फी कोड का उपयोग कर सकते हैं।

बेशक, यहां the official documentation page about thread safety in DWS है।

अब आप किसी दिए गए IdwsProgram के लिए के रूप में कई कार्यक्रम फांसी के रूप में आप चाहते हैं, प्रत्येक निष्पादन अपने ढेर & ढेर केवल, संकलित अभिव्यक्ति पेड़ साझा किया जाता है के लिए स्मृति का उपयोग करेगा हो सकता है। दोनों नए इंटरफेस संदर्भ-गिनती स्मृति प्रबंधन का उपयोग करते हैं।

+1

इसे पढ़कर, मुझे एहसास हुआ कि मुझे पहले से ही यह पता है, लेकिन जब तक कि मैं गलत नहीं हूं, यह मेरे प्रश्न का काफी जवाब नहीं देता है ... मैं एक ही स्क्रिप्ट को कई धागे में नहीं चलाना चाहता, मैं बनना चाहता हूं एक ही स्क्रिप्ट के अंदर कई धागे चला रहे हैं ... – FHannes

+1

AFAIK अब तक मैं निष्पादन वर्ग कार्यान्वयन को समझता हूं, डिजाइन द्वारा यह संभव नहीं है। कोई टीटीएचड या ऐसा नहीं है। एकमात्र संभावना प्रत्येक के लिए धागे के अंदर कई स्क्रिप्ट चलाने के लिए होगी (यह संभव है, ज़ाहिर है), फिर स्क्रिप्ट के बीच आईपीसी या म्यूटेक्स बनाने की कोशिश करें, जैसा कि मैंने अपने तीसरे बिंदु में लिखा था: थ्रेड संचार के बीच नहीं है खरोंच से उपलब्ध है। मैं डेल्फी कक्षाओं द्वारा उपलब्ध कराए गए कुछ साझा डेटा संरचनाओं के साथ एक स्टेटलेस आर्किटेक्चर की सिफारिश करता हूं (उदाहरण के लिए आरटीटीआई का उपयोग डीडब्ल्यूएस में किया गया है)। –

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