2016-03-07 17 views
5

यदि गो में एक चैनल पर एक बड़ी संरचना भेजी जाती है, तो क्या यह वास्तव में गोरोटाइन के बीच कॉपी की जाती है?क्या गोलांग चैनल पर भेजे जाने पर वास्तव में गोरोटाइन के बीच एक संरचना की प्रतिलिपि बनाई गई है?

उदाहरण के लिए, नीचे दिए गए कोड में, वास्तव में goroutines निर्माता और उपभोक्ता के बीच सभी बड़े संरचना डेटा कॉपी करेंगे?

package main 

import (
    "fmt" 
    "sync" 
) 

type largeStruct struct { 
    buf [10000]int 
} 

func main() { 
    ch := make(chan largeStruct) 
    wg := &sync.WaitGroup{} 
    wg.Add(2) 
    go consumer(wg, ch) 
    go producer(wg, ch) 
    wg.Wait() 
} 

func producer(wg *sync.WaitGroup, output chan<- largeStruct) { 
    defer wg.Done() 
    for i := 0; i < 5; i++ { 
     fmt.Printf("producer: %d\n", i) 
     output <- largeStruct{} 
    } 
    close(output) 
} 

func consumer(wg *sync.WaitGroup, input <-chan largeStruct) { 
    defer wg.Done() 
    i := 0 
LOOP: 
    for { 
     select { 
     case _, ok := <-input: 
      if !ok { 
       break LOOP 
      } 
      fmt.Printf("consumer: %d\n", i) 
      i++ 
     } 
    } 
} 

खेल का मैदान: http://play.golang.org/p/fawEQnSDwB

+2

वैकल्पिक रूप से, यदि संरचना में एक टुकड़ा होता है, '[] int', स्लाइस (और इसलिए संरचना) को पास करने का प्रभाव आंतरिक सरणी की प्रतिलिपि नहीं करेगा। मैं यह नहीं कह रहा हूं कि आपका जवाब हालांकि है। –

उत्तर

11

हाँ, सब कुछ जाने में एक प्रति है, आप आसानी से उस चैनल एक सूचक (उर्फ chan *largeStruct) का उपयोग करने बदलकर आसपास काम कर सकते हैं।

// डेमो: http://play.golang.org/p/CANxwt8s2B

आप देख सकते हैं, v.buf सूचक प्रत्येक मामले में अलग है, लेकिन अगर आप इसे chan *largeStruct को बदलने के लिए, संकेत एक ही हो जाएगा। https://play.golang.org/p/-VFWCgOnh0

रूप @nos ने बताया, वहाँ एक संभावित दौड़ है अगर आप इसे भेजने के बाद दोनों goroutines के मान में बदलाव:

@LucasJones उदाहरण का अनुसरण करने को थोड़ा आसान प्रदान की है।

+3

यहां दोनों प्रकार के चैनलों का एक खेल का मैदान प्रदर्शन है: https://play.golang.org/p/-VFWCgOnh0 –

+0

@ लुकास जोन्स मैं बेहतर दृश्यता के लिए पोस्ट में अपना उदाहरण जोड़ूंगा। – OneOfOne

+2

यदि आप केवल एक सूचक भेज रहे हैं तो बस संभावित दौड़ स्थितियों से अवगत रहें। आप एक ही संरचना के साथ गड़बड़ दोनों goroutines के साथ खत्म नहीं करना चाहते हैं – nos

4

The Go Programming Language Specification

Send statements

एक भेजने बयान एक चैनल पर एक मूल्य के लिए भेजता है। चैनल अभिव्यक्ति चैनल प्रकार का होना चाहिए, चैनल दिशा को संचालन भेजने की अनुमति देनी चाहिए, और भेजे जाने वाले मान के प्रकार को चैनल के तत्व प्रकार पर असाइन किया जाना चाहिए।

यह एक प्रति है क्योंकि चैनल को चैनल के तत्व प्रकार के लिए असाइनमेंट द्वारा चैनल भेजा जाता है। यदि मान एक संरचना है, तो संरचना की प्रतिलिपि बनाई जाती है। यदि मान एक संरचना के लिए एक सूचक है, तो संरचना के सूचक को कॉपी किया गया है।

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