"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > गो में समवर्ती पहुंच के लिए 'एपेंड' फ़ंक्शन थ्रेड-सुरक्षित क्यों नहीं है?

गो में समवर्ती पहुंच के लिए 'एपेंड' फ़ंक्शन थ्रेड-सुरक्षित क्यों नहीं है?

2024-11-11 को प्रकाशित
ब्राउज़ करें:519

Why is `append` function not thread-safe for concurrent access in Go?

अपेंड फ़ंक्शन: समवर्ती पहुंच के लिए थ्रेड-सुरक्षित नहीं है

जब लूप के भीतर एक स्लाइस में तत्वों को जोड़ने के लिए समवर्ती गोरोइन का उपयोग किया जाता है, तो विसंगतियां होती हैं डेटा में उत्पन्न हो सकता है. परिणामी स्लाइस में गुम या रिक्त डेटा दिखाई दे सकता है, जो संभावित डेटा दौड़ का संकेत देता है।

ऐसा इसलिए होता है क्योंकि गो में, एक साथ पढ़ने और लिखने के लिए कोई भी मान स्वाभाविक रूप से सुरक्षित नहीं है। स्लाइस, जो स्लाइस हेडर द्वारा दर्शाए जाते हैं, कोई अपवाद नहीं हैं। प्रदान किया गया कोड समवर्ती पहुंच के कारण डेटा दौड़ प्रदर्शित करता है:

destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        destSlice = append(destSlice, tmpObj)
    }(myObject)
}
wg.Wait()

डेटा रेस की उपस्थिति को सत्यापित करने के लिए, निम्नलिखित कमांड निष्पादित करें:

go run -race play.go

आउटपुट आपको डेटा के प्रति सचेत करेगा दौड़:

WARNING: DATA RACE
...

समवर्ती समस्याओं का समाधान

इस समस्या को हल करने के लिए, एक सिंक का उपयोग करके डेस्टस्लाइस तक लेखन पहुंच को सुरक्षित रखें। म्यूटेक्स:

var (
    mu        = &sync.Mutex{}
    destSlice = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()

वैकल्पिक रूप से, एपेंड्स को एसिंक्रोनस रूप से संभालने के लिए एक चैनल का उपयोग करने पर विचार करें:

var (
    appendChan = make(chan myClass)
    destSlice  = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        appendChan 
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3