2016-12-06 1 views
0

Как упоминалось в golang doc, синхронизация предназначена для низкоуровневых библиотечных процедур.Что такое правильный способ использования golang sync.WaitGroup

Помимо типов Once и WaitGroup, большинство из них предназначено для использования в низкоуровневых библиотечных подпрограммах . Более качественная синхронизация лучше осуществляется через каналы и связь.

Я не совсем понимаю это утверждение, и я использую синхронизацию, как в примере ниже.
Моя цель - только допустить, что основная тема будет ждать окончания всех остальных потоков, аналогично .join() в библиотеке потоков C++.

Вопросы:
1: Правильно ли использовать синхронизацию? Или я должен использовать канал вместо синхронизации?
2: В чем разница между каналом и синхронизацией?

var wg sync.WaitGroup  // declare the variable globally 

func send(a string, b string){ 
    defer wg.Done() 
    // do something 
} 
func main(){ 
    for i:=0; i<50; i++ { 
     wg.Add(1)    // add delta 
     go send("1111", "2222") 
    } 
    wg.Wait()     // wait until wg becomes 0 
} 

Любые предложения ценятся! Благодаря!

+1

Я не уверен, что вы просите, вы ваш 'send' goroutine имеет другой' sync.WaitGroup', чем в 'главный()', так что нет никакой синхронизации происходит. – JimB

+0

@JimB эй, извините за смутное заявление! Я обновил. На самом деле я использую sync здесь, чтобы сделать что-то вроде '.join()' в C++-потоке. Из документа, канал также может сделать это. Правильно ли использовать синхронизацию? – Eagle

+1

Да, для чего предназначена WaitGroup; ожидая группы горти. Я не понимаю вопроса о «правильном способе использования синхронизации», так как это целый пакет, и вы используете то, что он предоставляет, когда вам это нужно. Это невозможно использовать 'sync.WaitGroup', поскольку значение' wg' в 'main' отличается от значения' wg' в 'send'. – JimB

ответ

0

Этот пример может помочь вам

var wg sync.WaitGroup 
done := make(chan bool) 

for _, element := range slice { 
    wg.Add(1) 
    go func(elem interface{}) { 
     wg.Done() 
    }(element) 
} 

go func() { 
    wg.Wait() 
    done <- true 
}() 

for { 
    select { 
    case done: 
     fmt.Println("All goroutines completed") 
     close(done) 
     return 
    case time.After(time.Minute * 2): 
     fmt.Println("Timeout!") 
     return 
    } 
} 
0

Я не знаю, является ли это правильное, но ниже код делает трюк без использования более низкого уровня «синхронизации».

package main 

func send(a string, b string, c chan bool) { 
// println(a, b) 
    c <- true; 
} 

func 
main() { 

    c := make(chan bool) 

    for i:=0; i<50; i++ { 
     go send("1111", "2222", c) 
    } 

    w := 0 
    for _ = range c { 
     w += 1 
     if w == 50 { break } 
    } 

}