2016-08-15 8 views
5

मैं count संपत्ति के साथ struct है थ्रेड-सुरक्षित उपयोग करने के लिए की जरूरत है।क्या यह थ्रेड-सुरक्षित समवर्ती पहुंच के साथ है?

मैं इसे sync.Mutex या sync.RWMutex साथ किया जा सकता पता है। लेकिन मुझे यकीन नहीं है कि यह ठीक है:

type Status struct { 
    count uint32 

    attr1 string 
    attr2 string 
} 

func (s *Status) Get() uint32 { 
    return atomic.LoadUint32(&s.count) 
} 

func (s *Status) Add(n uint32) { 
    atomic.AddUint32(&s.count, n) 
} 

func (s *Status) Reset(n uint32) { 
    atomic.StoreUint32(&s.count, n) 
} 

धन्यवाद।

संपादित करें:

मैं उलझन में है कि पहुँच क्षेत्र सीधे s.count सुरक्षित नहीं है हूँ। लेकिन atomic.LoadUint32(&s.count) सुरक्षित है?

+0

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

उत्तर

3

हाँ, अगर केवल उन 3 तरीकों count क्षेत्र तक पहुँचने, अपने समाधान कई goroutines से साथ-साथ उपयोग के लिए सुरक्षित है।

लेकिन पता है कि Status.Get() द्वारा दिए गए मान "पुरानी" बार जब आप इसे उपयोग करने का प्रयास द्वारा हो सकता है। उदा .:

s := &Status{} 

if s.Get() == 3 { 
    fmt.Println(s.Get()) // This may or may not print 3 
} 

// Or 
c := s.Get() 
fmt.Println(c == s.Get()) // This may or may not print true 

ऊपर के उदाहरण या 3 और true प्रिंट नहीं हो सकता है के रूप में s.Get() लिए 2 कॉल एक और goroutine में s.Add() के लिए एक और कॉल द्वारा preceeded हो सकता है।

आपको गारंटी कि कोई भी किसी और संशोधित की जरूरत है या Status.count फ़ील्ड का मान तक पहुँचता है जब आप इसे पर आगे की गणना करते हैं, तो sync.Mutex या sync.RWMutex हैं, तो जाने के लिए रास्ता नहीं है के रूप में आप count मैदान पर एक ताला पकड़ कर सकते हैं, जबकि आप अपनी गणना खत्म करो।

संपादित करें:

s.count के लिए सीधी पहुँच, सुरक्षित नहीं है atomic.LoadUint32(&s.count) सुरक्षित है: अपने संपादित उत्तर देने के लिए। इसका कारण यह है कि अगर goroutine # 1 s.Add() पर कॉल करता है, और goroutine # 2 s.count तक पहुंचने का प्रयास करता है, तो कोई गारंटी नहीं है कि goroutine # 2 # 1 द्वारा किए गए परिवर्तन देखेंगे। # 2 में आप s.count की बस एक कैश्ड संस्करण देख सकते हैं।

स्पष्ट सिंक्रनाइज़ेशन के बिना आपको किसी अन्य goroutine में एक चर में किए गए परिवर्तनों का निरीक्षण करने की कोई गारंटी नहीं है। सीधे तक पहुँचने s.count एक अनसिंक्रनाइज़्ड उपयोग है। चैनल या अन्य सिंक्रनाइज़ेशन प्राइमेटिव्स का उपयोग (उदा। sync या sync/atomic पैकेज) s.count पर क्रमबद्ध पहुंच सुनिश्चित करता है, इसलिए ये समाधान हमेशा वर्तमान, अद्यतन मान देखेंगे।

जानकारी के लिए, यह लेख देखें: - या Erlang और अमृत या हास्केल की तरह हो सकता है कुछ शुद्ध कार्यात्मक भाषाओं कुछ भाषाओं है कि जटिल प्रकार प्रणाली है कि के हिस्से के रूप संगामिति पर विचार छोड़कर The Go Memory Model

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