यदि धागे एक ही पीआईडी ​​साझा करते हैं, तो उन्हें कैसे पहचाना जा सकता है?


98

मेरे पास लिनक्स में धागे के कार्यान्वयन से संबंधित एक प्रश्न है।

लिनक्स में स्पष्ट धागा समर्थन नहीं है। उपयोगकर्ता स्थान में, हम थ्रेड बनाने के लिए एक थ्रेड लाइब्रेरी (जैसे NPTL) का उपयोग कर सकते हैं। अब अगर हम NPTL का उपयोग करते हैं तो यह 1: 1 मैपिंग का समर्थन करता है।

कर्नेल clone()थ्रेड को लागू करने के लिए फ़ंक्शन का उपयोग करेगा ।

मान लीजिए मैंने 4 धागे बनाए हैं। तो इसका मतलब यह होगा कि:

  • 4 होंगे task_struct
  • अंदर task_struct, वहाँ क्लोन करने के लिए तर्क के अनुसार संसाधनों को साझा करने का प्रावधान किया जाएगा (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)

अब मेरे पास निम्नलिखित प्रश्न हैं:

  1. क्या 4 थ्रेड्स में एक ही पीआईडी ​​होगी? यदि कोई विस्तृत कर सकता है, तो पीआईडी ​​को कैसे साझा किया जाता है।
  2. विभिन्न धागों की पहचान कैसे की जाती है; क्या कुछ TID (थ्रेड आईडी) अवधारणा है?

जवाबों:


275

चार धागों में एक ही पीआईडी ​​होगी लेकिन केवल ऊपर से देखने पर। जिसे आप (एक उपयोगकर्ता के रूप में) पीआईडी ​​कहते हैं वह नहीं है जो कर्नेल (नीचे से देख रहा है) एक पीआईडी ​​कहलाता है।

में गिरी, प्रत्येक थ्रेड उसके अपने आईडी, (हालांकि यह संभवतः इस एक टीआईडी, या धागे आईडी कॉल करने के लिए और अधिक समझ बनाने के हैं) और वे भी एक TGID (धागा समूह आईडी) एक पीआईडी कहा जाता है जो धागे की पीआईडी है इसने पूरी प्रक्रिया शुरू कर दी।

सरलीकृत रूप से, जब एक नई प्रक्रिया बनाई जाती है, तो यह एक थ्रेड के रूप में प्रकट होता है, जहां पीआईडी ​​और टीजीआईडी ​​दोनों एक ही (नई) संख्या होती हैं।

जब कोई थ्रेड कोई दूसरा थ्रेड प्रारंभ करता है , तो प्रारंभ किया गया थ्रेड अपना PID प्राप्त करता है (इसलिए शेड्यूलर इसे स्वतंत्र रूप से शेड्यूल कर सकता है) लेकिन यह TGID को मूल थ्रेड से इनहेरिट करता है।

इस तरह, कर्नेल खुशी से थ्रेड्स को शेड्यूल कर सकता है कि वे किस प्रक्रिया से संबंधित हैं, जबकि प्रोसेस (थ्रेड ग्रुप आईडी) आपको बताए जाते हैं।

धागे की निम्नलिखित पदानुक्रम मदद कर सकते हैं (ए) :

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW

आप देख सकते हैं कि एक नई प्रक्रिया शुरू करना (बाईं ओर) आपको एक नया पीआईडी और एक नया TGID (दोनों एक ही मूल्य पर सेट) देता है, जबकि एक नया सूत्र (दाईं ओर) शुरू करते हुए आपको एक नया PID प्रदान करता है टीजीआईडी ​​उस धागे के रूप में जिसने इसे शुरू किया था।


(ए) मेरे प्रभावशाली चित्रमय कौशल पर विस्मयकारी :-)


20
FYI करें, getpid()tgid लौटाता है: asmlinkage long sys_getpid(void) { return current->tgid;}जैसा कि www.makelinux.com/
Duke

6
@ ड्यूक - वाह, यही कारण है कि मैं एक gettgid(2)समारोह नहीं मिल सका । और getpid()TID (थ्रेड के "PID") को वापस नहीं किया जाएगा, और वहाँ है जहाँ gettid(2)अंदर आता है। इस तरह से मैं बता सकता हूं, अगर हम मुख्य थ्रेड में हैं या नहीं।
टॉमस गैंडर

2
यह एक और दिलचस्प बिंदु की ओर जाता है: इसलिए यदि थ्रेड और प्रक्रियाओं को कर्नेल के भीतर समान रूप से संभाला जाता है (tgid के अलावा), तो बहु-थ्रेडेड प्रक्रिया को एक-थ्रेडेड की तुलना में अधिक CPU समय मिलेगा, बशर्ते कि दोनों समान हों प्राथमिकता और कोई भी सूत्र किसी भी कारण से रुका हुआ नहीं है (जैसे कि म्यूटेक्स की प्रतीक्षा करना)।
एककनगुआ

1
@Aconcagua, CFS (लिनक्स में पूरी तरह से निष्पक्ष अनुसूचक) आम तौर पर इस तरह से काम करता है, लेकिन समूह शेड्यूलर एक्सटेंशन के उपयोग से व्यक्तिगत कार्यों के बजाय निष्पक्षता को कार्यों के कुछ समूहों में संचालित करने की अनुमति देता है। मैंने वास्तव में इसे सरसरी निगाह से इतर नहीं देखा है।
paxdiablo

'' getpgrp '' पाने के लिए समूह आईडी
Pengcheng

2

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

नोट: यह मेरी कर्नेल 2.6.36 की याद से है। वर्तमान कर्नेल संस्करणों में मेरा काम I / O परत में है, इसलिए मुझे नहीं पता कि क्या तब से बदल गया है।


-6

लिनक्स fork()एक प्रक्रिया को डुप्लिकेट करने की पारंपरिक कार्यक्षमता के साथ सिस्टम कॉल प्रदान करता है। लिनक्स clone()सिस्टम कॉल का उपयोग करके थ्रेड बनाने की क्षमता भी प्रदान करता है हालांकि, लिनक्स प्रक्रियाओं और थ्रेड के बीच अंतर नहीं करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.