Several pits of channel and waitgroup in golang

package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

type BBB struct {
    
    
	ctx             context.Context
	chBalanceUpdate chan string
}

func (b *BBB) dosome() {
    
    

	wg := sync.WaitGroup{
    
    }
	defer wg.Wait()
	for {
    
    
		select {
    
    
		case address, ok := <-b.chBalanceUpdate:
			if !ok {
    
    
				fmt.Println(" channel is closed")
				// return
			}

			// create new goroutine to update balance
			wg.Add(1)
			fmt.Printf("%p", &address)
			go func(addr string, w *sync.WaitGroup) {
    
      PANIC
				defer w.Done()
				// get balance of addr and update into database
				// b.updateBalance(addr)
				fmt.Printf("============do something============:%v\n", address)
			}(address, &wg) // 必须使用  &wg, 而不是 wg
		}
		// time.Sleep(time.Second * 1)
	}
}

func (b *BBB) doother() {
    
    
	for  {
    
    
		time.Sleep(time.Millisecond * 10)
		b.chBalanceUpdate <- fmt.Sprintf("hello: %v", time.Now().Unix())
	}
	// close(b.chBalanceUpdate)
	// fmt.Println("=======close channel============")
}

func main() {
    
    

	// chBalanceUpdate :=

	bb := BBB{
    
    
		ctx:             context.Background(),
		chBalanceUpdate: make(chan string, 0), // 如果是有buffer的,即当buffer没满的时候就是非阻塞的,那么读取端就是非阻塞的
	}

	wg := sync.WaitGroup{
    
    }
	wg.Add(1)
	go func() {
    
    
		defer wg.Done()
		bb.doother()
	}()

	wg.Add(1)
	go func() {
    
    
		defer wg.Done()
		bb.dosome()
	}()

	wg.Wait()
}

Guess you like

Origin blog.csdn.net/yqq1997/article/details/130267426