2012-09-08 9 views
7

(उत्तर के साथ इस पोस्ट कर रहा है, क्योंकि मैं यह कैसे कहीं भी करने के लिए की पूरी जानकारी के नहीं मिल सकता है, तो मैंने सोचा कि यह किसी के लिए कुछ मूल्य हो सकता है)सेट धागा प्रोसेसर आत्मीयता नेट

मैं कैसे कर सकता है माइक्रोसॉफ्ट .NET में किसी विशेष थ्रेड के प्रोसेसर एफ़िनिटी सेट करें? प्रक्रिया के संबंध की स्थापना के माध्यम से System.Diagnostics.Process.ProcessorAffinity तुच्छ है, लेकिन System.Threading.Thread वर्ग में ऐसी कोई कार्यक्षमता प्रदान करता है और नेट की गारंटी नहीं है एक प्रबंधित धागा किसी विशेष ऑपरेटिंग सिस्टम धागा से जुड़ा हुआ है।

उत्तर

25

के बीच अलगाव में कामयाब रहे और ऑपरेटिंग सिस्टम धागे वापस नेट 2.0 तिथियाँ, और SQL सर्वर टीम द्वारा योजनाओं फाइबर का उपयोग नेट धागे लागू करने के लिए। यह वास्तव में कहीं भी नहीं चला, इसलिए इस बात की कोई गारंटी नहीं है कि एक प्रबंधित थ्रेड हमेशा एक ही ऑपरेटिंग सिस्टम थ्रेड पर चलता रहेगा, प्रैक्टिस में यह हमेशा सभी मौजूदा नेट होस्ट के लिए होता है। यह देखते हुए कि नेट 2.0 के परिचय के बाद से यह सभी वर्षों में नहीं बदला है, यह असंभव है कि यह कभी भी बदलेगा।

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

.Net System.Diagnostics.ProcessThread कक्षा का उपयोग कर देशी ऑपरेटिंग सिस्टम थ्रेड तक पहुंचने की क्षमता प्रदान करता है, और इस वर्ग में ProcessorAffinity संपत्ति का उपयोग करके थ्रेड के प्रोसेसर एफ़िनिटी को बदलने की क्षमता है। हालांकि, किसी विशेष प्रबंधित थ्रेड को ProcessThread से लिंक करना जानबूझकर मुश्किल बना दिया गया था।

यह करने के लिए केवल असली तरीका धागा के भीतर की है। System.AppDomain.GetCurrentThreadId विधि का उपयोग करें (या PInvoke GetCurrentThreadId समारोह यदि आप एक पदावनत विधि कॉल नहीं करना चाहती है, हालांकि कि विंडोज के अलावा अन्य ऑपरेटिंग सिस्टम पर मोनो के साथ काम नहीं होगा)। इसके बाद ProcessThread.Id संपत्ति से मेल खाया जा सकता है।

यह यह संभव निम्न कोड के साथ थ्रेड प्रोसेसर आत्मीयता स्थापित करने के लिए बनाता है (धागा अंदर से के नाम से जाना):

/// <summary> 
/// Sets the processor affinity of the current thread. 
/// </summary> 
/// <param name="cpus">A list of CPU numbers. The values should be 
/// between 0 and <see cref="Environment.ProcessorCount"/>.</param> 
public static void SetThreadProcessorAffinity(params int[] cpus) 
{ 
    if(cpus == null) 
     throw new ArgumentNullException("cpus"); 
    if(cpus.Length == 0) 
     throw new ArgumentException("You must specify at least one CPU.", "cpus"); 

    // Supports up to 64 processors 
    long cpuMask = 0; 
    foreach(int cpu in cpus) 
    { 
     if(cpu < 0 || cpu >= Environment.ProcessorCount) 
      throw new ArgumentException("Invalid CPU number."); 

     cpuMask |= 1L << cpu; 
    } 

    // Ensure managed thread is linked to OS thread; does nothing on default host in current .Net versions 
    Thread.BeginThreadAffinity(); 

#pragma warning disable 618 
    // The call to BeginThreadAffinity guarantees stable results for GetCurrentThreadId, 
    // so we ignore the obsolete warning 
    int osThreadId = AppDomain.GetCurrentThreadId(); 
#pragma warning restore 618 

    // Find the ProcessThread for this thread. 
    ProcessThread thread = Process.GetCurrentProcess().Threads.Cast<ProcessThread>() 
           .Where(t => t.Id == osThreadId).Single(); 
    // Set the thread's processor affinity 
    thread.ProcessorAffinity = new IntPtr(cpuMask); 
} 

ध्यान रखें कि जबकि इस नेट के वर्तमान संस्करण पर काम करता है, सैद्धांतिक रूप से गारंटी की कमी है कि प्रबंधित धागे ओएस धागे से बंधे हैं, भविष्य में इस कोड को तोड़ सकते हैं। हालांकि, मैं इसे बेहद असंभव मानता हूं।

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