एक थ्रेड से थ्रेड आईडी प्राप्त करना


319

उदाहरण के लिए थ्रेड डीबग करते समय C # में, आप प्रत्येक थ्रेड की आईडी देख सकते हैं।

मैं प्रोग्रामिक रूप से उसी थ्रेड को प्राप्त करने का कोई तरीका नहीं खोज सका। मुझे वर्तमान थ्रेड की आईडी (संपत्तियों में Thread.currentThread) भी नहीं मिली ।

तो, मुझे आश्चर्य है कि विज़ुअल स्टूडियो को थ्रेड्स की आईडी कैसे मिलती है, और क्या आईडी के साथ थ्रेड का हैंडल प्राप्त करने का एक तरीका है 2345, उदाहरण के लिए?

जवाबों:


437

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

GetCurrentThreadId वर्तमान थ्रेड की आईडी लौटाता है।

GetCurrentThreadId.NET 2.0 के रूप में पदावनत किया गया है: अनुशंसित तरीका Thread.CurrentThread.ManagedThreadIdसंपत्ति है।


87
जब से मैंने यह पाया, इसे टाइप किया, और फिर यह बताया गया कि यह पदावनत किया गया था, ऐसा करने का वर्तमान तरीका थ्रेड है। CurrentThread.ManagedThreadId
James

3
ManagedThreadId थ्रेड की पहचान करने के लिए एक मजबूत तरीका नहीं है क्योंकि ManagedThreadId प्रॉपर्टी आईडी आपके ऐप द्वारा पुन: उपयोग किया जाता है। तो यह कुछ परिदृश्यों में धागे के लिए एक विश्वसनीय पहचानकर्ता नहीं है और आप अपवाद का अनुभव करेंगे: "उसी कुंजी के साथ एक आइटम पहले से ही जोड़ा गया है।" जब आप इसे बनाते हैं, तो लाइन को एक अनूठा नाम दें।
फोरनर

15
इस पोस्ट पर कुछ बहुत बुरी सलाह दी जा रही है। कुछ लोग एक सूत्र की पहचान करने के लिए "ManagedThreadId" का उपयोग करने की सिफारिश कर रहे हैं। मैंने सिफारिश को हटाने के लिए पोस्ट को संपादित किया - बहुत कम लोगों ने बताया है कि विभिन्न प्रकार के थ्रेड आईडी हैं। प्रबंधित थ्रेड आईडी मानव रहित थ्रेड आईडी के समान नहीं हैं, और यदि लोग उस कोड को कॉपी और पेस्ट करना चाहते हैं जो कुछ बहुत ही सूक्ष्म सिंक्रनाइज़ेशन बग हो सकते हैं। थ्रेड वर्ग के लिए MSDN पर प्रलेखन इस बारे में बहुत स्पष्ट है। कक्षा स्तर पर टिप्पणियों को देखें।
शैडोचैस्टर

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

11
मैं इस टिप्पणी को ध्यान में रखते हुए पोस्ट करना चाहूंगा जो System.Threading.Thread.CurrentThread.ManagedThreadIdकम से कम उपयोग करते समय काम नहीं करेगा SetWindowsHookEx। इसके बजाय हमें मूल win32 फ़ंक्शन से थ्रेड आईडी प्राप्त करना होगा GetCurrentThreadId()
राजा राजा

82

उदाहरण के लिए थ्रेड डीबग करते समय C # में, आप प्रत्येक थ्रेड की आईडी देख सकते हैं।

यह प्रबंधित थ्रेड्स के Ids होंगे। ManagedThreadIdका एक सदस्य है Threadतो आप किसी भी थ्रेड ऑब्जेक्ट से आईडी प्राप्त कर सकते हैं । यह आपको वर्तमान ManagedThreadID मिलेगा :

Thread.CurrentThread.ManagedThreadId

इसके द्वारा OS थ्रेड प्राप्त करने के लिए OS थ्रेड आईडी (ManagedThreadID नहीं) , आप थोड़ा सा linq आज़मा सकते हैं।

int unmanagedId = 2345;
ProcessThread myThread = (from ProcessThread entry in Process.GetCurrentProcess().Threads
   where entry.Id == unmanagedId 
   select entry).First();

ऐसा लगता है कि प्रबंधित थ्रेड्स को एन्यूमरेट करने का कोई तरीका नहीं है और ProcessThread और Thread के बीच कोई संबंध नहीं है, इसलिए Id द्वारा प्रबंधित थ्रेड प्राप्त करना एक कठिन है।

प्रबंधित बनाम अप्रबंधित सूत्रण के बारे में अधिक जानकारी के लिए यह MSDN आर्कटिक देखें ।


4
इस सरल उत्तर के साथ कोई और क्यों नहीं आया?
स्टीफन स्टाइनगर्गर

2
यह काम नहीं करता। GetCurrentProcess ()। थ्रेड्स एक ProcessThreadCollection लौटाता है, जो थ्रेड्स के लिए परिवर्तनीय नहीं है। मैं एक आसान तय नहीं दिख रहा हूँ।
मफू २५'११

2
@ mafutrct, अद्यतन उत्तर। उस संपत्ति को वास्तव में कहा जाना चाहिए। धन्यवाद।
badbod99

2
अनुशंसा करें कि इस पोस्ट को यह स्पष्ट करने के लिए फिर से लिखा जाए कि दोनों थ्रेड आईडी अलग-अलग हैं। यदि कोई अंतिम वाक्य को पढ़ने में विफल रहता है, तो वे सिर्फ ManagedThreadId को प्लग करेंगे और इसे प्रोसेसट्रेड के खिलाफ मैप करने का प्रयास करेंगे। मैं, जो कहर पैदा कर रहा है।
शैडोचैस्टर

1
मैंने अंतर को उजागर करने वाले एक सहायक MSDN एक्टिकल का लिंक जोड़ा है। हालांकि, यह प्रश्न डिबगिंग के लिए थ्रेड आईडी प्राप्त करने से संबंधित था (जो इस मामले में ManagedThreadID है)। मुझे नहीं लगता कि ओएस और प्रबंधित थ्रेड्स के बीच अंतर के विवरण के साथ उत्तर को अव्यवस्थित करना उपयोगी है।
badbod99

46

आप AppDomain.GetCurrentThreadIdवर्तमान में चल रहे धागे की आईडी प्राप्त करने के लिए पदावनत का उपयोग कर सकते हैं । यह विधि Win32 API विधि के लिए PInvoke का उपयोग करती है GetCurrentThreadID, और Windows थ्रेड ID लौटाएगी।

इस विधि को पदावनत के रूप में चिह्नित किया जाता है क्योंकि .NET थ्रेड ऑब्जेक्ट किसी एकल विंडोज थ्रेड के अनुरूप नहीं है, और जैसे कि कोई स्थिर आईडी नहीं है जिसे विंडोज द्वारा किसी दिए गए .NET थ्रेड के लिए वापस किया जा सकता है।

ऐसा क्यों होता है, इसके कारणों के लिए विन्यासकर्ता का उत्तर देखें।


.Net Core 2.2 के साथ ध्यान दें, ध्यान दें कि AppDomain.GetCurrentThreadId (मैं MethodInfo द्वारा अप्रचलित के रूप में इनवॉइस किया गया) प्रबंधित थ्रेड आईडी (मिलान प्रक्रिया के लिए बेकार है।
GetCurrentProcess

32

OS ID का उपयोग करने के लिए:

AppDomain.GetCurrentThreadId()

1
GetHashCode जरूरी अद्वितीय नहीं है! और एक धागे की पहचान करने के लिए इसका इस्तेमाल नहीं करना चाहिए।
Dror Helper

2
यदि आप OS थ्रेड आईडी चाहते हैं, तो आप AppDomain.GetCurrentThreadId () का उपयोग कर सकते हैं, लेकिन कई .NET थ्रेड्स में एक ही OS थ्रेड साझा किया जा सकता है। Thread.GetHashCode () को एक मान वापस करने की गारंटी है जो अद्वितीय प्रक्रिया-चौड़ा है, जो कि आप शायद चाहते हैं।
मार्क बायर्स

3
विधि को पदावनत के रूप में चिह्नित किया गया है, और अच्छे कारण के साथ। कृपया फुलर चित्र के लिए मेरा उत्तर और विन्यासकर्ता देखें।
पॉल टर्नर

3
वैसे यह OS थ्रेड आईडी पाने का एकमात्र तरीका है। और इसे सही उत्तर के रूप में चिह्नित किया जाना चाहिए। हालांकि यह है कि मैं इस पर और अधिक भरोसा नहीं करने जा रहा हूँ।
लोलारून

1
AppDomain.GetCurrentThreadId()अप्रचलित है: AppDomain.GetCurrentThreadId हटा दिया गया है क्योंकि यह एक स्थिर आईडी प्रदान नहीं करता है जब प्रबंधित थ्रेड चल रहे हैं fibers (aka lightweight threads)। प्रबंधित थ्रेड के लिए एक स्थिर पहचानकर्ता प्राप्त करने के लिए, ManagedThreadIdसंपत्ति का उपयोग करें Thread। उपयोग:Thread.CurrentThread.ManagedThreadId
लिजो जोसेफ

22

MSDN के अनुसार :

एक ऑपरेटिंग-सिस्टम थ्रेडआईड का प्रबंधित थ्रेड से कोई निश्चित संबंध नहीं है, क्योंकि एक अप्रबंधित होस्ट प्रबंधित और अनवांटेड थ्रेड्स के बीच संबंध को नियंत्रित कर सकता है। विशेष रूप से, एक परिष्कृत होस्ट एक ही ऑपरेटिंग सिस्टम थ्रेड के विरुद्ध कई प्रबंधित थ्रेड शेड्यूल करने के लिए या विभिन्न ऑपरेटिंग सिस्टम थ्रेड्स के बीच प्रबंधित थ्रेड को स्थानांतरित करने के लिए CLR होस्टिंग API का उपयोग कर सकता है।

तो मूल रूप से, Threadऑब्जेक्ट जरूरी एक ओएस थ्रेड के अनुरूप नहीं है - यही कारण है कि इसमें मूल आईडी उजागर नहीं है।


VS2010 में डिबग / थ्रेड्स विंडो "प्रबंधित थ्रेड आईडी" से पता चलता है। मैं इसे कैसे प्राप्त कर सकता हूं?
पावेल रेडविलविलोव्स्की

1
ManagedThreadID प्रॉपर्टी का उपयोग करें msdn.microsoft.com/en-us/library/… । हालांकि यह ओएस थ्रेड आईडी के समान नहीं है।
विन्यासकर्ता

15

हैक करने वालों के बारे में:

    public static int GetNativeThreadId(Thread thread)
    {
        var f = typeof(Thread).GetField("DONT_USE_InternalThread",
            BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

        var pInternalThread = (IntPtr)f.GetValue(thread);
        var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 548 : 348); // found by analyzing the memory
        return nativeId;
    }

11

वर्तमान थ्रेड आईडी का उपयोग करने के लिए - `Thread.CurrentThread.ManagedThreadId '। लेकिन इस मामले में आपको वर्तमान win32 थ्रेड आईडी की आवश्यकता हो सकती है - इस फ़ंक्शन के साथ इसे प्राप्त करने के लिए pInvoke का उपयोग करें:

[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
public static extern Int32 GetCurrentWin32ThreadId();

पहले आपको प्रबंधित थ्रेड आईडी और win32 थ्रेड आईडी कनेक्शन को बचाने की आवश्यकता होगी - एक ऐसे शब्दकोश का उपयोग करें जो एक थ्रेड आईडी को प्रबंधित थ्रेड में मैप करता है।

फिर प्रोसेस आईडी के थ्रेड पर प्रक्रिया it.GetCurrentProcess () का उपयोग करके इसे खोजने के लिए एक थ्रेड ढूंढते हैं। थ्रेड्स और उस आईडी के साथ थ्रेड ढूंढते हैं:

foreach (ProcessThread thread in Process.GetCurrentProcess().Threads)
{
     var managedThread = win32ToManagedThread[thread.id];
     if((managedThread.ManagedThreadId == threadId)
     {
         return managedThread;
     }
}

मेरा मानना ​​है कि ओपी थ्रेड की ओएस आईडी के लिए पूछ रहा है, जो प्रबंधित थ्रेड आईडी के समान नहीं है।
ब्रायन रासमुसेन

यह कोड काम नहीं करता है: Process.Threads ProcessThreadवस्तुओं का एक संग्रह लौटाता है , यह उसी तरह नहीं है (और न ही यह वारिस है) Thread: (thread as Thread)एक अशक्त संदर्भ लौटाएगा।
फ्रेड्रिक मोर्क

मैंने देखा है कि कोड कोड में कुछ कीड़े थे - इसे अभी आज़माएं
Dror Helper

1
मैंने एक शब्दकोश का उपयोग करते हुए समाप्त किया जो win32 आईडी को एक प्रबंधित धागे में मैप करता है।
कंटीनो

11

Windows 10 के अंतर्गत ऑफ़सेट 0x022C (x64-bit-Application) और 0x0160 (x32-bit-Application) हैं:

public static int GetNativeThreadId(Thread thread)
{
    var f = typeof(Thread).GetField("DONT_USE_InternalThread",
        BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);

    var pInternalThread = (IntPtr)f.GetValue(thread);
    var nativeId = Marshal.ReadInt32(pInternalThread, (IntPtr.Size == 8) ? 0x022C : 0x0160); // found by analyzing the memory
    return nativeId;
}

1
SP1 के साथ ही विंडोज 7 x64 पर काम करता है। हालांकि अनुशंसित नहीं। केवल अस्थायी परीक्षण में उपयोग करें।
गुआन बोशेन

5

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId

5

प्रबंधित कोड से आपके पास Threadप्रत्येक प्रबंधित थ्रेड के प्रकार के उदाहरणों तक पहुंच है । Threadएक OS थ्रेड की अवधारणा को एनकोड करता है और वर्तमान सीएलआर के रूप में प्रबंधित थ्रेड्स और ओएस थ्रेड्स के साथ एक-से-एक पत्राचार है। हालाँकि, यह एक कार्यान्वयन विवरण है, जो भविष्य में बदल सकता है।

विजुअल स्टूडियो द्वारा प्रदर्शित आईडी वास्तव में ओएस थ्रेड आईडी है। यह प्रबंधित थ्रेड आईडी के समान नहीं है जैसा कि कई उत्तरों द्वारा सुझाया गया है।

Threadप्रकार एक निजी IntPtr सदस्य बुलाया क्षेत्र शामिल नहीं है DONT_USE_InternalThread, जो अंक अंतर्निहित ओएस संरचना करने के लिए। हालाँकि, जैसा कि यह वास्तव में एक कार्यान्वयन विवरण है, इस IMO को आगे बढ़ाने के लिए उचित नहीं है। और इस तरह का नाम इंगित करता है कि आपको इस पर भरोसा नहीं करना चाहिए।


GetThreadId का उपयोग करने के लिए आपको हैंडल की आवश्यकता होगी - जो आपको DONT_USE फ़ील्ड से मिलता है।
विन्यासकर्ता

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

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

@OhrmaZd: हां, VS2005 / 2008 थ्रेड विंडो में प्रबंधित थ्रेड्स के लिए OS ID दिखाता है। VS2010B2 वास्तव में प्रति थ्रेड OS और प्रबंधित ID दोनों दिखाता है।
ब्रायन रासमुसेन

@ ब्रायन रासमुसेन: अब यह एक प्रबंधित धागे की पहचान है! अपनी जानकारी साझा करने के लिए धन्यवाद।
लोला रुन

4

आप Thread.GetHashCode का उपयोग कर सकते हैं, जो प्रबंधित थ्रेड आईडी लौटाता है। यदि आप GetHashCode के उद्देश्य के बारे में सोचते हैं, तो यह अच्छा अर्थ है - इसे ऑब्जेक्ट (थ्रेड) के लिए एक अद्वितीय पहचानकर्ता (उदाहरण के लिए एक शब्दकोश में कुंजी) होना चाहिए।

थ्रेड वर्ग के लिए संदर्भ स्रोत यहाँ शिक्षाप्रद है। (दी, एक विशेष नेट कार्यान्वयन सकता है आधारित नहीं इस स्रोत कोड पर है, लेकिन डीबगिंग उद्देश्यों मैं अपने जोखिम लेने के लिए।)

GetHashCode "एल्गोरिदम के लिए यह हैश कोड प्रदान करता है, जिसे ऑब्जेक्ट समानता की त्वरित जांच की आवश्यकता होती है," इसलिए यह थ्रेड समानता की जांच करने के लिए अच्छी तरह से अनुकूल है - उदाहरण के लिए यह सुनिश्चित करने के लिए कि एक विशेष विधि उस थ्रेड पर निष्पादित हो रही है जिसे आप इसे कहते थे।


4
बहुत बढ़िया, मैं सिर्फ एक घंटे के लिए खुला 5 साल पुराना सवाल था, वापस आया और देखा "इस सवाल का 1 नया जवाब": D
Ray

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

अच्छी तरह से मैं एक अलग क्षेत्र में अभी हूँ, लेकिन फिर, हम एक धागे के लिए दो आईडी, मूल धागे की आईडी, और प्रबंधित धागे के लिए एक आईडी था, और एक दूसरे से संबंधित है ... मुख्यतः, आईडी से थ्रेड्स की पहचान करने का इरादा है, गेटहैशकोड की अन्य उपयोगिता है, और टकरा सकती है। अगर हमें
GetHashCode

3
@yoyo Collisions शब्दकोश के उपयोग को नहीं तोड़ता है। वे टकराव की कम संभावना के लिए डिज़ाइन किए गए हैं, बिल्कुल टक्कर नहीं। यदि आपके पास 64 बिट मान के लिए 128 बिट मान है तो प्रत्येक हैश मान में लगभग 2 ^ 64 टकराव होंगे। डिक्शनरी में एक फॉलबैक एल्गोरिदम होने के लिए डिज़ाइन किया गया है जब एक दुर्लभ स्थिति में टकराव होता है।
ब्रैडगोनसर्फिंग

2
@bradgonesurfing आप बिल्कुल सही हैं, और मेरी पिछली टिप्पणी गलत है। शब्दकोश प्रदर्शन हैश टकराव के साथ नीचा दिखाना होगा, लेकिन कार्यक्षमता सही है। भ्रामक टिप्पणी के लिए मेरी क्षमा याचना, उस ओर इशारा करने के लिए धन्यवाद।
योयो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.