Golang阻塞编程的实现

2,083 阅读1分钟

sync.WaitGroup

func main () {
    var wg sync.WaitGroup
    wg.Add(1)
    wg.Wait() // 只要等待wg.Done()调用才会继续执行之后的代码
}

空select

func main () {
    go func (){
        // 执行到select代码之后,会执行到此处代码
    }()
    select{} // CPU在执行到该行代码时,会让出时间片。
    fmt.Println("print end") // 该行代码用于不会执行
}

有没有能够让程序切换时间片之后,继续切换会之前的上下文继续执行代码,可以使用runtime.Gosched()

func main () {
    go func (){
        //(2)执行到select代码之后,会执行到此处代码
    }()
    runtime.Gosched() // (1) CPU在执行到该行代码时,会让出时间片。
    fmt.Println("print end") // (3) 在执行完2之后,继续执行该行代码。
}

for死循环

func main () {
    for{} // 一般不会如此使用,会在for循环之内增加睡眠的逻辑,保证不会一直暂用CPU资源
}

sync.Mutex

对于已经被锁了的锁,如果再锁一次就会一直阻塞。

func main () {
    var m sync.Mutex
    m.Lock()
    m.Lock()
}

channel阻塞

func main () {
    c := make(chan struct{})
    <- c // 空chan,没有值写入c中,阻塞于此
}
func main () {
    var c  chan struct{}
    <- c // nil chan,没有值写入c中,阻塞于此
}

os.Signal

使用系统信号量,本质上是个channel,在收到特定的消息之前一直阻塞。

func main () {
    sig := make(chan os.Signal, 2)
    signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
    <-sig
}

参考文章: