কোনও থ্রেড থেকে থ্রেড আইডি পাওয়া


319

সি # তে উদাহরণস্বরূপ থ্রেডগুলি ডিবাগ করার সময় আপনি প্রতিটি থ্রেডের আইডি দেখতে পারেন।

প্রোগ্রামটিমে আমি একই থ্রেড পাওয়ার কোনও উপায় খুঁজে পাইনি। আমি বর্তমান থ্রেডের আইডিও পেতে পারি না (এর বৈশিষ্ট্যগুলিতে Thread.currentThread)।

সুতরাং, আমি ভাবছি কীভাবে ভিজ্যুয়াল স্টুডিও থ্রেডগুলির আইডি পেয়েছে এবং 2345উদাহরণস্বরূপ, আইডির সাহায্যে থ্রেডটির হ্যান্ডেলটি পাওয়ার কোনও উপায় আছে ?

উত্তর:


437

GetThreadIdপ্রদত্ত নেটিভ থ্রেডের আইডি প্রদান করে। এটি পরিচালিত থ্রেডগুলির সাথে কাজ করার উপায় রয়েছে, আমি নিশ্চিত, আপনার যা অনুসন্ধান করা দরকার তা হ'ল থ্রেড হ্যান্ডেল এবং এটিকে ফাংশনে প্রেরণ করা।

GetCurrentThreadId বর্তমান থ্রেডের আইডি প্রদান করে।

GetCurrentThreadId.NET 2.0 হিসাবে অবচয় করা হয়েছে: প্রস্তাবিত উপায় Thread.CurrentThread.ManagedThreadIdসম্পত্তি is


87
যেহেতু আমি এটি পেয়েছি, এটি টাইপ করেছি এবং তারপরে বলা হয়েছিল যে এটি অবমূল্যায়ন করা হয়েছে, এটি করার বর্তমান উপায় হ'ল থ্রেড। কর্নারথ্যাড.ম্যানেজডথ্রেডআইডি
জেমস

3
ম্যানেজডথ্রেডআইড থ্রেডগুলি সনাক্ত করার জন্য মজবুত পন্থা নয় কারণ ম্যানেজডথ্রেডআইডি সম্পত্তি আইডিটি আপনার অ্যাপ্লিকেশনটির মাধ্যমে পুনরায় ব্যবহার করা যায়। সুতরাং এটি কিছু পরিস্থিতিতে থ্রেডগুলির জন্য নির্ভরযোগ্য সনাক্তকারী নয় এবং আপনি ব্যতিক্রমটি অনুভব করতে পারেন: "একই কী সহ একটি আইটেম ইতিমধ্যে যুক্ত করা হয়েছে।" লাইনে ... থ্রেডটি তৈরি করার সময় একটি অনন্য নাম দিন।
Forer

15
এই পোস্টে প্রায় খুব খারাপ পরামর্শ ঘুরছে। কিছু লোক একটি থ্রেড সনাক্ত করতে "ম্যানেজডথ্রেডআইডি" ব্যবহার করার পরামর্শ দিচ্ছেন। আমি প্রস্তাবটি সরাতে পোস্টটি সম্পাদনা করেছি - খুব কম লোকই কী বলেছে যে বিভিন্ন ধরণের থ্রেড আইডি রয়েছে। পরিচালিত থ্রেড আইডিগুলি নিয়ন্ত্রণহীন থ্রেড আইডির মতো জিনিস নয় এবং লোকেরা যদি সেই কোডটি অনুলিপি করে আটকে দেয় তবে কিছু খুব সূক্ষ্ম সিঙ্ক্রোনাইজেশন বাগ হতে পারে। থ্রেড ক্লাসের জন্য এমএসডিএন-তে ডকুমেন্টেশন এ সম্পর্কে খুব স্পষ্ট। ক্লাস স্তরে মন্তব্যগুলি দেখুন।
ShadowChaser

3
আপনি আইডির ক্ষেত্রে সিঙ্ক্রোনাইজ করবেন না, আপনি মুটেক্সেসের মতো সিঙ্ক্রোনাইজেশন আদিম ব্যবহার করেন। এটি কেবল ডিবাগিংয়ের উদ্দেশ্যে।
অন্ধ

11
আমি এই মন্তব্যটি পোস্ট করতে চাই তা লক্ষ্য করার জন্য যে System.Threading.Thread.CurrentThread.ManagedThreadIdকোনওটিতে ব্যবহার করার সময় কমপক্ষে কাজ করবে না SetWindowsHookEx। পরিবর্তে আমাদের দেশীয় win32 ফাংশন থেকে থ্রেড আইডি পেতে হবে GetCurrentThreadId()
কিং কিং

82

সি # তে উদাহরণস্বরূপ থ্রেডগুলি ডিবাগ করার সময় আপনি প্রতিটি থ্রেডের আইডি দেখতে পারেন।

এটি পরিচালিত থ্রেডগুলির আইডি হবে। ManagedThreadIdএর সদস্য Threadতাই আপনি যে কোনও থ্রেড অবজেক্ট থেকে আইডিটি পেতে পারেন । এটি আপনাকে বর্তমান পরিচালিত ট্র্যাডআইডিআইডি পাবে :

Thread.CurrentThread.ManagedThreadId

এটির ওএস থ্রেড আইডি (ম্যানেজডথ্রেডআইডি নয়) এর মাধ্যমে কোনও ওএস থ্রেড পেতে আপনি কিছুটা লিনক চেষ্টা করতে পারেন।

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

মনে হচ্ছে পরিচালিত থ্রেডগুলি গণনার কোনও উপায় নেই এবং প্রসেসথ্রেড এবং থ্রেডের মধ্যে কোনও সম্পর্ক নেই, সুতরাং এটির আইডির মাধ্যমে পরিচালিত থ্রেড পাওয়া শক্ত কাজ।

পরিচালিত বনাম অব্যবস্থাপনাযুক্ত থ্রেডিং সম্পর্কিত আরও তথ্যের জন্য এই এমএসডিএন আর্টিকেলটি দেখুন


4
কেন এই সহজ উত্তর নিয়ে অন্য কেউ আসেনি?
স্টিফান স্টেইনেগার

2
এটা কাজ করে না. গেটক্র্যান্টপ্রসেস ()। থ্রেডগুলি একটি প্রসেসথ্রেডকলক্লেশন প্রদান করে, যা থ্রেডে রূপান্তরযোগ্য নয়। আমি একটি সহজ সংশোধন দেখতে পাচ্ছি না।
মাফু

2
@ mafutrct, আপডেট উত্তর। সেই সম্পত্তিটিকে সত্যই ডাকা উচিত T ধন্যবাদ।
Badbod99

2
দুটি থ্রেড আইডির চেয়ে পৃথক হওয়ার বিষয়টি স্পষ্ট করে তুলতে এই পোস্টটি পুনরায় লেখার পরামর্শ দিন। যদি কেউ শেষ বাক্যটি পড়তে ব্যর্থ হয়, তবে তারা কেবল ম্যানেজডথ্রেডআইডি প্লাগ করবে এবং প্রসেসথ্রেড-এর বিপরীতে এটি মানচিত্রের চেষ্টা করবে,
ShadowChaser

1
আমি পার্থক্যটি হাইলাইট করে একটি সহায়ক এমএসডিএন অ্যাক্টিকেলে একটি লিঙ্ক যুক্ত করেছি। তবে, প্রশ্নটি ডিবাগিংয়ের জন্য থ্রেড আইডি পাওয়ার সাথে সম্পর্কিত ছিল (যা এই ক্ষেত্রে ম্যানেজডথ্রেডআইডি)। আমি ওএস এবং পরিচালিত থ্রেডের মধ্যে পার্থক্যের বিশদ সহ উত্তরকে বিশৃঙ্খলা করা দরকারী বলে মনে করি না।
Badbod99

46

আপনি AppDomain.GetCurrentThreadIdবর্তমানে চলমান থ্রেডের আইডি পেতে অবহেলিত ব্যবহার করতে পারেন । এই পদ্ধতিটি উইন 32 এপিআই পদ্ধতিতে একটি পিনভোক ব্যবহার করে GetCurrentThreadIDএবং উইন্ডোজ থ্রেড আইডি ফিরিয়ে দেবে।

এই পদ্ধতিটি অবচিত হিসাবে চিহ্নিত করা হয়েছে কারণ .NET থ্রেড অবজেক্টটি একটি উইন্ডোজ থ্রেডের সাথে সামঞ্জস্য করে না এবং এর মতো কোনও স্থিতিশীল আইডি নেই যা কোনও প্রদত্ত .NET থ্রেডের জন্য উইন্ডোজ দ্বারা ফিরে আসতে পারে।

কেন এই ঘটনাটি আরও কারণের জন্য কনফিগারারের উত্তর দেখুন।


নেট কোর ২.২ সহ সতর্কতা, নোট করুন যে অ্যাপডোমাইন.গেটকন্ট্রেন্টথ্রেডআইডি (আমি অপ্রোসলেট হিসাবে মেথডেইনফো মাধ্যমে আহবান করেছি) পরিচালিত থ্রেড আইডি (প্রসেসের সাথে মিলিত করার জন্য বেহুদা। গেটক্র্যান্টপ্রসেস () থ্রেডস সংগ্রহ সংগ্রহ করে
ব্রিউম্যানজ

32

ওএস আইডি ব্যবহার পেতে:

AppDomain.GetCurrentThreadId()

1
গেটহ্যাশকোড অগত্যা অনন্য নয়! এবং এটি কোনও থ্রেড সনাক্ত করতে ব্যবহার করা উচিত নয়।
ড্রয়ার হেল্পার

2
আপনি ওএস থ্রেড আইডি চাইলে অ্যাপডোমাইন.গেটকন্ট্রেন্টথ্রেডআইডি () ব্যবহার করতে পারেন তবে একাধিক নেট নেট থ্রেড থিওরীতে একই ওএস থ্রেড ভাগ করতে পারে। থ্রেড.গেটহ্যাশকোড () এমন একটি মান ফেরৎ দেওয়ার গ্যারান্টিযুক্ত যা প্রসেস-ওয়াইড-অনন্য, যা সম্ভবত আপনি চান।
মার্ক বাইয়ার্স

3
পদ্ধতিটি অবচয় হিসাবে চিহ্নিত করা হয়েছে, এবং সঙ্গত কারণেই। পূর্ণাঙ্গ চিত্রের জন্য দয়া করে আমার উত্তর এবং কনফিগারারের দেখুন।
পল টার্নার

3
ওয়েল এটি ওএস থ্রেড আইডি পাওয়ার একমাত্র উপায়। এবং এটি সঠিক উত্তর হিসাবে চিহ্নিত করা উচিত। যদিও আমি এর উপর আর নির্ভর করতে যাচ্ছি না।
LolaRun

1
AppDomain.GetCurrentThreadId()অপ্রচলিত: অবহিত AppDomain.GetCurrentThreadId করা হয়েছে কারণ এটি পরিচালিত থ্রেড চলমান থাকলে স্থিতিশীল আইডি সরবরাহ করে না fibers (aka lightweight threads)। পরিচালিত থ্রেডের জন্য একটি স্থিতিশীল শনাক্তকারী পেতে, ManagedThreadIdসম্পত্তিটি ব্যবহার করুন Thread। ব্যবহার:Thread.CurrentThread.ManagedThreadId
লিজো জোসেফ

22

এমএসডিএন অনুসারে :

একটি অপারেটিং-সিস্টেম থ্রেডআইডের একটি পরিচালিত থ্রেডের সাথে কোনও স্থির সম্পর্ক নেই, কারণ একটি পরিচালনা না করা হোস্ট পরিচালনা করা এবং পরিচালনা না করা থ্রেডের মধ্যে সম্পর্ক নিয়ন্ত্রণ করতে পারে। বিশেষত, একটি পরিশীলিত হোস্ট একই অপারেটিং সিস্টেম থ্রেডের বিপরীতে অনেকগুলি পরিচালিত থ্রেড নির্ধারণ করতে, বা বিভিন্ন অপারেটিং সিস্টেমের থ্রেডের মধ্যে পরিচালিত থ্রেড সরাতে সিএলআর হোস্টিং এপিআই ব্যবহার করতে পারে।

সুতরাং মূলত, Threadঅবজেক্টটি অপরিহার্যভাবে কোনও ওএস থ্রেডের সাথে সামঞ্জস্য করে না - যার কারণে এটির নেটিভ আইডি উন্মুক্ত হয় না।


ভিএস2010-এ ডিবাগ / থ্রেডস উইন্ডোটি "পরিচালিত থ্রেড আইডি" দেখায়। আমি কীভাবে এটি পেতে পারি?
পাভেল রদজিভিলভস্কি

1
ManagedThreadID সম্পত্তি ব্যবহার করুন msdn.microsoft.com/en-us/library/... । এটি যদিও ওএস থ্রেড আইডিটির মতো নয়।
Configurator

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;
    }

বর্ধিত জন্য upvated কিন্তু বর্তমানে কাজ করছে না।
টেকমিজএগুয়েস্ট

11

বর্তমান থ্রেড আইডি ব্যবহার করতে - `থ্রেড.কন্ট্রেন্টথ্রেড.ম্যানেজডথ্রেডআইডি '। তবে এক্ষেত্রে আপনার বর্তমান উইন 32 থ্রেড আইডি দরকার হতে পারে - এই ফাংশনটি পেতে এটি পিনভোক ব্যবহার করুন:

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

প্রথমে আপনাকে পরিচালিত থ্রেড আইডি এবং উইন 32 থ্রেড আইডি সংযোগ সংরক্ষণ করতে হবে - এমন একটি অভিধান ব্যবহার করুন যা পরিচালিত থ্রেডে একটি win32 আইডি মানচিত্র করে।

তারপরে তার আইডি দ্বারা একটি থ্রেড সন্ধান করতে প্রক্রিয়াটির থ্রেডটি প্রসেস.গেটকন্টারপ্রসেস () ব্যবহার করে পুনরাবৃত্তি করুন। থ্রেডগুলি এবং সেই আইডি সহ থ্রেডটি সন্ধান করুন:

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

আমি বিশ্বাস করি যে ওপি থ্রেডের ওএস আইডি চাইছে, যা পরিচালিত থ্রেড আইডির মতো নয়।
ব্রায়ান রাসমুসেন

এই কোডটি কাজ করে না: প্রক্রিয়া.ত্যাগগুলি ProcessThreadবস্তুর সংকলন প্রদান করে, এটি (যেমনটি উত্তরাধিকার সূত্রে প্রাপ্ত হয় না) এর মতো নয় Thread: (thread as Thread)নাল রেফারেন্স প্রদান করবে।
ফ্রেড্রিক মার্ক

আমি লক্ষ্য করেছি যে কোড কোডটিতে কয়েকটি বাগ রয়েছে - এটি এখনই চেষ্টা করে স্থির করে ফেলুন
ডারার হেল্পার

1
আমি একটি অভিধান ব্যবহার করে শেষ করেছি যা একটি পরিচালিত থ্রেডে একটি win32 আইডি মানচিত্র করে।
কনটাঙ্গো

11

উইন্ডোজ 10 এর অধীনে অফসেটটি 0x022C (x64-বিট-অ্যাপ্লিকেশন) এবং 0x0160 (x32-বিট-অ্যাপ্লিকেশন):

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
উইন্ডোজ 7 এক্স 64 এর সাথে এসপি 1 এর সাথেও কাজ করে। যদিও পুনঃসামূলক নয়। অস্থায়ী পরীক্ষায় কেবল ব্যবহার করুন।
গুয়ান বোশেন

5

System.Threading.Thread.CurrentThread.Name

System.Threading.Thread.CurrentThread.ManagedThreadId

5

পরিচালিত কোড থেকে আপনার Threadপ্রতিটি পরিচালিত থ্রেডের জন্য ধরণের দৃষ্টান্তগুলিতে অ্যাক্সেস রয়েছে । Threadএকটি ওএস থ্রেডের ধারণাটি সজ্জিত করে এবং বর্তমান সিএলআর হিসাবে পরিচালিত থ্রেড এবং ওএস থ্রেডের সাথে একের সাথে একটি চিঠিপত্র রয়েছে। তবে এটি একটি বাস্তবায়ন বিশদ, এটি ভবিষ্যতে পরিবর্তন হতে পারে।

ভিজ্যুয়াল স্টুডিও দ্বারা প্রদর্শিত আইডি আসলে ওএস থ্রেড আইডি। এই না পরিচালিত থ্রেড আইডি হিসাবে একই হিসাবে বিভিন্ন প্রত্যুত্তর দ্বারা প্রস্তাবিত।

Threadটাইপ একটি প্রাইভেট IntPtr সদস্য নামক ক্ষেত্র অন্তর্ভুক্ত করে DONT_USE_InternalThread, যা পয়েন্ট অন্তর্নিহিত অপারেটিং সিস্টেম কাঠামো। তবে এটি বাস্তবায়নের বিশদ হিসাবে এটি এই আইএমও অনুসরণ করা ঠিক হবে না। এবং নাম সাজানোর ইঙ্গিত দেয় যে আপনার উপর নির্ভর করা উচিত নয়।


গেটথ্রেডআইড ব্যবহার করতে আপনার হ্যান্ডেলটি দরকার - যা আপনি DONT_USE ক্ষেত্র থেকে পান।
কনফিগারকারী

আমি জানি, তবে যেমনটি আমি বলেছিলাম যে আপনি সত্যই ওএস থ্রেডগুলিতে পরিচালিত থ্রেডের মানচিত্রগুলিতে নির্ভর করতে পারবেন না, সুতরাং আমি এটিতে বিশ্বাস করব না।
ব্রায়ান রাসমুসেন

স্পষ্টতা, এবং সমস্যার সংমিশ্রনের জন্য অনেক ধন্যবাদ। তবে এখন যদি একাধিক পরিচালিত থ্রেডগুলি কোনও একক ওএস থ্রেডের সাথে সামঞ্জস্য করতে পারে (যেমন কনফিগারেটর বলেছেন - এবং তিনি ধন্যবাদ জানায়), তার মানে ভিএস ওএস থ্রেড প্রদর্শন করছে এবং পরিচালিত থ্রেডগুলি নয়।
LolaRun

@ অরমাজেডডি: হ্যাঁ, ভিএস 2003/2008 থ্রেডস উইন্ডোটিতে পরিচালিত থ্রেডের জন্য ওএস আইডি দেখায়। VS2010B2 আসলে প্রতিটি থ্রেডে ওএস এবং পরিচালিত আইডি উভয়ই দেখায়।
ব্রায়ান রাসমুসেন

@ ব্রায়ান রাসমুসেন: এখন এটি একটি পরিচালিত থ্রেডের একটি পরিচয়! তোমার অভিজ্ঞতা ভাগাভাগি করার জন্য ধন্যবাদ।
লোলাআর

4

আপনি থ্রেড.গেটহ্যাশকোড ব্যবহার করতে পারেন, যা পরিচালিত থ্রেড আইডি দেয়। যদি আপনি গেটহ্যাশকোডের উদ্দেশ্য সম্পর্কে ভাবেন, তবে এটি ভাল ধারণা দেয় - এটি অবজেক্টের (থ্রেড) জন্য একটি অনন্য সনাক্তকারী (উদাহরণস্বরূপ অভিধানে কী) হওয়া দরকার।

থ্রেড বর্গ জন্য রেফারেন্স উৎস এখানে শিক্ষণীয়। (মঞ্জুর, একটি নির্দিষ্ট .NET বাস্তবায়ন করতে পারে ভিত্তিক করা এই উৎস কোডের উপর কিন্তু ডিবাগ করার উদ্দেশ্যে আমি আমার সম্ভাবনা নেব জন্য।)

গেটহ্যাশকোড "এই অ্যালগরিদমের জন্য এই হ্যাশ কোড সরবরাহ করে যার জন্য বস্তুর সমতার দ্রুত চেক প্রয়োজন," সুতরাং এটি থ্রেড সাম্যতা যাচাইয়ের জন্য উপযুক্ত - উদাহরণস্বরূপ যে কোনও নির্দিষ্ট পদ্ধতিটি থ্রেডে যেটি আপনি চেয়েছিলেন তা চালিয়ে যাচ্ছে sert


4
আশ্চর্যজনক, আমি এই মাত্র 5 বছরের পুরানো প্রশ্নটি এক ঘন্টার জন্য উন্মুক্ত রেখেছি এবং ফিরে এসে "এই প্রশ্নের 1 টি নতুন উত্তর" দেখেছি: ডি
রায়

এই উত্তরটি অন্য একটি মন্তব্যে ইঙ্গিত করা হয়েছিল, তবে এটিই আমি আরও কিছু গবেষণার পরে ব্যবহার করে শেষ করেছি। সম্ভবত ওপি যা চেয়েছিল তা নয়। সম্ভবত ওপি আর যত্ন করে না। অন্য কারও কাজে লাগতে পারে। (এবং কমপক্ষে রেফারেন্স উত্সের ভিত্তিতে, থ্রেড আইডি পাওয়ার এটি সবচেয়ে কার্যকর উপায় হতে পারে))
yoyo

ঠিক আছে আমি এই মুহুর্তে অন্য এক ফিল্ডে আছি, তবে তারপরে, আমাদের একটি থ্রেডের জন্য দুটি আইডি ছিল, নেটিভ থ্রেডের আইডি, এবং পরিচালিত থ্রেডের জন্য একটি আইডি, এবং একটি অন্যটির সাথে সম্পর্কিত ... মূলত: আইডিগুলির উদ্দেশ্য থ্রেডগুলি চিহ্নিত করার উদ্দেশ্যে করা হয়, গেটহ্যাশকোডগুলির অন্যান্য ইউটিলিটি রয়েছে এবং সংঘর্ষ হতে পারে। ফ্রেমওয়ার্ক বিকাশকারীরা যদি আইডি প্রয়োগ না করতেন তবে আমাদের যদি গেটহ্যাশকোড
লোলাআর

3
@ ইয়ায়ো সংঘর্ষগুলি অভিধানের ব্যবহার ভাঙবে না। এগুলি সংঘর্ষের সম্ভাবনা কম হওয়ার জন্য ডিজাইন করা হয়েছে, কোনও সংঘর্ষ নয়। যদি আপনি একটি 648 মানের একটি 128 বিটের মান হ্যাশ করে থাকেন তবে প্রতিটি হ্যাশ মানটির প্রায় 2 ^ 64 সংঘর্ষ হবে। বিরল ক্ষেত্রে যখন কোনও সংঘর্ষ হয় তখন অভিধানটি ফ্যালব্যাক অ্যালগরিদম তৈরির জন্য তৈরি করা হয়।
ব্র্যাডগোনসার্ফিং

2
আপনি @ একেবারে ঠিক বলেছেন, এবং আমার আগের মন্তব্যটি ভুল। অভিধানের পারফরম্যান্স হ্যাশের সংঘর্ষের সাথে হ্রাস পাবে, তবে কার্যকারিতা সঠিক থাকবে। বিভ্রান্তিকর মন্তব্যের জন্য আমার ক্ষমাপ্রার্থনা, এটিকে নির্দেশ করার জন্য ধন্যবাদ।
yoyo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.