2009-06-01 20 views
10

मैं एकाधिक थ्रेड से एक हस्ताक्षरित पूर्णांक को बढ़ाना चाहता हूं।सी # बहु-थ्रेडेड हस्ताक्षरित वृद्धि

मुझे इंटरलाक्ड.इंटरमेंट के बारे में पता है, लेकिन यह हस्ताक्षरित पूर्णांक को संभाल नहीं करता है। मैं लॉक() का उपयोग कर सकता हूं, लेकिन प्रदर्शन कारणों से मैं संभव नहीं हूं।

क्या यह सामान्य तरीके से इसे बढ़ाने के लिए सुरक्षित है? इससे कोई फर्क नहीं पड़ता कि कभी-कभी वृद्धि हुई है, क्योंकि इसका उपयोग केवल आंकड़ों के लिए किया जाता है। जो मैं नहीं चाहता वह दूषित होने का मूल्य है।

उत्तर

-11

आप अवांछित के रूप में यूंट घोषित कर सकते हैं।

http://msdn.microsoft.com/en-us/library/x13ttww7(VS.71).aspx

+7

यह केवल यह सुनिश्चित करता है कि v में कोई भी परिवर्तन आभासी तुरंत स्मृति के लिए लिखा जाता है, जब तक थ्रेड पैदावार या मूल्य को किसी रजिस्टर में विस्थापित नहीं किया जाता है, तब तक प्रतीक्षा करने की बजाय। यह क्षेत्र तक पहुंच की रक्षा नहीं करता है, यानी दो (या अधिक) धागे एक ही मूल्य को पढ़ सकते हैं, एक बार वृद्धि कर सकते हैं, और लिख सकते हैं, प्रभावी ढंग से मूल्य को बढ़ाकर 1. –

+0

कृपया उपर्युक्त आवश्यकताओं को पढ़ें और उदाहरण भी http: //msdn.microsoft.com/en-us/library/7a2f3ay4.aspx। दिए गए मामले के लिए यह पर्याप्त है। – Sesh

+0

Interlocked.Increment की तुलना में निष्पादक अस्थिर है? वही? बेहतर? – jrista

9

तुम सच में पूरा एक अहस्ताक्षरित int की रेंज (2^32 - 1) की जरूरत है न कि एक हस्ताक्षरित पूर्णांक (2^31 -1), आप एक int64 लिए डाली सकता है (वहाँ है एक Interlocked.Increment अधिभार जो int64 लेता है) और फिर एक हस्ताक्षरित int पर वापस डाला।

+0

यह मेरी पसंद भी होगी। – ChrisBD

+3

ध्यान दें कि इंटरलाक्ड। इंक्रुमेंट (रेफरी लांग) केवल 64-बिट ओएस के तहत वास्तव में परमाणु है (प्रलेखन देखें) – jerryjvl

+2

व्यक्तिगत रूप से मैं सामान्य सुरक्षा के लिए नियमित int के साथ करता हूं ... यदि 31 बिट पर्याप्त नहीं है, तो मुझे संदेह है कि 32 वास्तव में बहुत बेहतर काम करेगा, जब तक समस्या 2 जी और 4 जी माप के बीच बिल्कुल प्रतिबंधित नहीं होती है। – jerryjvl

30

आप कहते हैं कि आप प्रदर्शन कारणों से lock का उपयोग नहीं करना चाहते हैं - लेकिन आपने इसका परीक्षण किया है? एक अनचाहे लॉक (जो इसकी आवाज़ से होने की संभावना है) बहुत सस्ता है।

जब मैं थ्रेडिंग (और सामान्य रूप से, लेकिन विशेष रूप से थ्रेडिंग के लिए) आता हूं तो मैं आमतौर पर "चालाक और संभवतः बेहतर प्रदर्शन" के बजाय "स्पष्ट रूप से सही" के लिए जाता हूं।

लॉकिंग के साथ और बिना अपने ऐप को बेंचमार्क करें, और देखें कि क्या आप अंतर भी देख सकते हैं। यदि लॉकिंग महत्वपूर्ण अंतर बनाता है तो सुनिश्चित करें कि चालाक सामान का उपयोग करें। अन्यथा, मैं बस एक ताला के साथ रहना होगा।

using System; 
using System.Reflection; 
using System.Threading; 

public class Test 
{ 
    private static int count = int.MaxValue-1; 

    public static uint IncrementCount() 
    { 
     int newValue = Interlocked.Increment(ref count); 
     return (uint) newValue; 
    } 

    public static void Main() 
    { 
     Console.WriteLine(IncrementCount()); 
     Console.WriteLine(IncrementCount()); 
     Console.WriteLine(IncrementCount()); 
    } 

} 

आउटपुट::

2147483647 
2147483648 
2147483649 

(

एक बात आप क्या करना चाहते हो सकता है एक int साथ Interlocked.Increment का उपयोग करें और बस जब आवश्यक एक uint पाने के लिए यह डाली, इस तरह है दूसरे शब्दों में यह किसी भी समस्या के साथ लपेटता है।)

+1

मैं सहमत हूं कि क्यों जटिल चीजें वास्तव में एक मुद्दा बन जाती हैं। मैं कल्पना नहीं कर सकता कि एक सिंगल वैल्यू बढ़ाने के लिए लॉक बहुत लंबे समय तक रहना है या ज्यादा संसाधनों का उपयोग करना है। सुरक्षित रैप-अप के लिए – PeteT

+0

+1! – Galilyou

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