2009-12-11 16 views
41

मैं जावा थ्रेड और देशी थ्रेड चलाने में कैसे अंतर करूं?जावा थ्रेड और ओएस धागे के बीच अंतर?

लिनक्स में प्रत्येक बच्चे की प्रक्रिया के लिए अभिभावक प्रक्रिया होगी, और वे कहते हैं कि 0 सभी प्रक्रियाओं का अभिभावक है, क्या सभी फोर्क किए गए जावा थ्रेड का अभिभावक धागा होगा?

मुझे कैसे पता चलेगा कि कौन सा जावा थ्रेड ओएस थ्रेड से संबंधित है (यदि जावा थ्रेड एक मूल प्रक्रिया धागा फॉर्क्स करता है)।

क्या जावा थ्रेड और ओएस धागे का कोई नामकरण सम्मेलन है?

क्या चल रहे जावा थ्रेड को किसी अन्य जावा कोड से निलंबित या मार दिया जा सकता है?

+0

स्टीफन सी, मैं सीख रहा हूं कि लिनक्स थ्रेड नामकरण और जावा थ्रेड नामकरण कैसे संबंधित हैं। और साथ ही, लिनक्स के भीतर कैसे JVM थ्रेड प्रबंधन प्रबंधित किया जाता है। – karthi

उत्तर

61

लिनक्स पर, जावा धागे देशी धागे के साथ कार्यान्वित किए जाते हैं, इसलिए धागे का उपयोग कर एक जावा प्रोग्राम थ्रेड का उपयोग करके देशी प्रोग्राम से अलग नहीं होता है। एक "जावा थ्रेड" एक जेवीएम प्रक्रिया से संबंधित एक धागा है।

एक आधुनिक लिनक्स सिस्टम (एनपीटीएल का उपयोग करने वाले) पर, किसी प्रक्रिया से संबंधित सभी थ्रेडों में एक ही प्रक्रिया आईडी और पैरेंट प्रोसेस आईडी होती है, लेकिन विभिन्न थ्रेड आईडी होती हैं। आप ps -eLf चलाकर इन आईडी को देख सकते हैं। पीआईडी ​​कॉलम प्रक्रिया आईडी है, पीपीआईडी ​​कॉलम पेरेंट प्रोसेस आईडी है, और एलडब्ल्यूपी कॉलम थ्रेड (लाइटवेइट प्रोसेस) आईडी है। "मुख्य" थ्रेड में एक थ्रेड आईडी होती है जो प्रक्रिया आईडी के समान होती है, और अतिरिक्त थ्रेड में अलग-अलग थ्रेड आईडी मान होंगे।

पुराने लिनक्स सिस्टम "लिनक्सथ्रेड" थ्रेडिंग कार्यान्वयन का उपयोग कर सकते हैं, जो एनपीटीएल के बजाय पूरी तरह से पॉज़िक्स-अनुरूप नहीं है। Linuxthreads सिस्टम पर, धागे की अलग प्रक्रिया आईडी होती है।

आप जांच सकते हैं कि आपका सिस्टम सिस्टम की सी लाइब्रेरी (libc) को एक स्टैंडअलोन प्रोग्राम के रूप में चलाकर और उसके आउटपुट में "उपलब्ध एक्सटेंशन" के अंतर्गत देखकर एनपीटीएल या लिनक्सथ्रेड का उपयोग कर रहा है या नहीं। इसे या तो "मूल पॉज़िक्स थ्रेड लाइब्रेरी" या लिनक्सथ्रेड का उल्लेख करना चाहिए। सी लाइब्रेरी का मार्ग सिस्टम से सिस्टम में भिन्न होता है: यह /lib/libc.so.6, /lib64/libc.so.6 (64-बिट रेडहाट-आधारित सिस्टम पर), या /lib/x86_64-linux-gnu/libc.so.6 (आधुनिक डेबियन-आधारित सिस्टम जैसे उबंटू) पर हो सकता है।

ओएस स्तर पर, पैरों के नाम नहीं हैं; वे केवल जेवीएम के भीतर मौजूद हैं।

pthread_kill() सी फ़ंक्शन का उपयोग किसी विशिष्ट थ्रेड को सिग्नल भेजने के लिए किया जा सकता है, जिसे आप JVM के बाहर से उस विशिष्ट थ्रेड को मारने का प्रयास करने के लिए उपयोग कर सकते हैं, लेकिन मुझे नहीं पता कि JVM इसका जवाब कैसे देगा। यह सिर्फ पूरे जेवीएम को मार सकता है।

+0

धन्यवाद वार्ड, क्या मैं थ्रेड चलाने के थ्रेड और क्वेरी विवरण का नाम दे सकता हूं? मैं डिबगिंग परिप्रेक्ष्य से पूछ रहा हूँ। – karthi

+0

एक थ्रेड का "नाम" जावा-विशिष्ट है; यह देखने के लिए कि आपको डीबगर के साथ JVM से कनेक्ट करना होगा। जेवीएम के बाहर से आप केवल अपनी संख्यात्मक आईडी देख सकते हैं, जो कि पॉज़िक्स स्टैंडपॉइंट से इसका एकमात्र पहचानकर्ता है। – Wyzard

+0

शैल प्रॉम्प्ट में जावा थ्रेड नाम प्रदर्शित करने के लिए क्या करना चाहिए? यदि मैं अपने प्रोफाइलर या डीबगर को चल रहे JVM से संलग्न करता हूं, तो क्या मैं चल रहे जावा थ्रेड नाम और शैल स्क्रिप्ट को आपूर्ति कर पाऊंगा? – karthi

8

कोई मानक नहीं है; यह पूरी तरह से जावा कार्यान्वयन पर निर्भर करता है जिसका आप उपयोग कर रहे हैं। इसके अलावा, "देशी धागे" और "मूल प्रक्रियाओं" को मिलाएं। एक प्रक्रिया एक पृथक इकाई है जो अन्य प्रक्रियाओं के पता स्थान में नहीं देख पाती है। एक धागा ऐसा कुछ होता है जो मूल प्रक्रिया के पता स्थान में चलता है और जो एक ही प्रक्रिया के अन्य धागे की स्मृति में देख सकता है।

लिनक्स पर आप जो देखते हैं वह कुछ और है: लिनक्स के कुछ संस्करण पेरेंट प्रक्रिया के प्रत्येक थ्रेड के लिए प्रक्रिया तालिका में एक प्रविष्टि बनाते हैं। ये "प्रक्रियाएं" असली प्रक्रिया नहीं हैं (अलगाव भावना में)। वे धागे हैं जिन्हें ps कमांड के साथ सूचीबद्ध किया जा सकता है। आप उस प्रक्रिया को पा सकते हैं जिसने उन्हें मूल पीआईडी ​​(पीपीआईडी) का उपयोग करके बनाया है।

4

कोई सामान्य समाधान नहीं है कि जावा थ्रेड्स को ओएस थ्रेड्स में कैसे मैप किया जाता है, अगर बिल्कुल भी। प्रत्येक जेवीएम कार्यान्वयन इसे एक अलग तरीके से कर सकता है।

एक शुद्ध जावा थ्रेड कार्यान्वयन भी है, जिसे green threads कहा जाता है। यदि मूल धागे समर्थित नहीं हैं या सिस्टम बिल्कुल बहुप्रचारित नहीं है तो इसका उपयोग फ़ॉलबैक के रूप में किया जाता है। आपको अपने ओएस पर कोई हरा धागा नहीं दिखाई देगा।

क्या चल रहे जावा थ्रेड को किसी अन्य जावा कोड से निलंबित या मार दिया जा सकता है?

यदि वे एक ही JVM पर चल रहे हैं, हाँ, स्टॉप() के साथ। लेकिन यह एक अच्छा समाधान नहीं है और काम कर सकता है, या नहीं। इंटरप्ट() थ्रेड को इतनी सुरक्षित रूप से बंद कर देता है।

मुझे पता है कि जेवीएम के बाहर धागे को मारने का कोई तरीका नहीं है। यदि एक ओएस वास्तव में धागे की हत्या का समर्थन करता है, तो मैं जावा एप्लिकेशन को बाद में सही ढंग से चलाने की उम्मीद नहीं करता!

5

एक चल जावा धागे निलंबित या किसी अन्य जावा कोड से मार डाला हो सकता है कर सकते हैं?

सिद्धांत रूप में हाँ। अभ्यास में, Thread.kill() और Thread.suspend() विधियों को बहिष्कृत कर दिया गया है क्योंकि वे बहुत सीमित परिस्थितियों को छोड़कर असुरक्षित हैं। मूल समस्या यह है कि जावा थ्रेड को मारने या निलंबित करने पर अन्य धागे को गड़बड़ करने की संभावना है जो उस पर निर्भर करता है, और साझा डेटा संरचनाओं को अद्यतन करने के बीच में हो सकता है।

यदि "अन्य जावा कोड" का अर्थ किसी अन्य JVM के लिए है, तो इसके काम करने की संभावनाएं भी कम हैं। भले ही आपने यह पता लगाया कि प्रासंगिक थ्रेड सिग्नल कैसे भेजना है, परिणाम पूरी तरह से अप्रत्याशित हैं। मेरी शर्त यह है कि "लक्ष्य" जेवीएम दुर्घटनाग्रस्त हो जाएगा।

+0

आप कुछ जेवीएम के तहत चल रहे एक विशिष्ट थ्रेड को मारने के लिए अपने जावा कोड से लिनक्स कमांड निष्पादित कर सकते हैं। आप विंडोज़ पर भी ऐसा कर सकते हैं। लेकिन मुझे लगता है कि आप शायद सही हैं जो उस धागे के parenting JVM को क्रैश कर देगा। यदि आप दोनों कार्यक्रमों को नियंत्रित करते हैं तो आपको शायद किसी अन्य प्रक्रिया में धागे को बताने के लिए कुछ प्रकार की आईपीसी कॉल विकसित करनी चाहिए। – PSIXO

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