Go基础编程实践(七)—— 并发
程序员文章站
2022-05-23 19:21:36
同时运行多个函数 观察常规代码和并发代码的输出顺序。 通道的关闭 Go // 生产者关闭通道 package main import ( "time" "fmt" ) func main() { channel := make(chan string) go func() { names := [] ......
同时运行多个函数
观察常规代码和并发代码的输出顺序。
// 常规代码,顺序执行,依次输出 package main import ( "fmt" "time" ) func main() { strn := []string{"a", "b", "c", "d"} for _, strv := range strn { time.sleep(time.second) fmt.println(strv) } intn := []int{1, 2, 3, 4} for _, intv := range intn { time.sleep(time.second) fmt.println(intv) } }
// 并发代码,并发执行,无序输出 package main import ( "fmt" "time" ) func main() { go func() { strn := []string{"a", "b", "c", "d"} for _, strv := range strn { time.sleep(time.second) fmt.println(strv) } }() go func() { intn := []int{1, 2, 3, 4} for _, intv := range intn { time.sleep(time.second) fmt.println(intv) } }() // 防止main routine过早退出 time.sleep(10 * time.second) }
通道的关闭
// 生产者关闭通道 package main import ( "time" "fmt" ) func main() { channel := make(chan string) go func() { names := []string{"jack", "mike", "john", "kitty"} for _, name := range names { time.sleep(time.second) // fmt.println(name) channel <- name } // 发送完毕关闭通道,否则引起死锁 close(channel) }() for data := range channel { fmt.println(data) } }
在通道中传递数据
// 利用无缓冲通道同步传递数据 package main import "fmt" func main(){ namechannel := make(chan string) done := make(chan string) go func(){ names := []string {"tarik", "michael", "gopi", "jessica"} for _, name := range names { fmt.println("processing the first stage of: " + name) namechannel <- name } close(namechannel) }() go func(){ for name := range namechannel{ fmt.println("processing the second stage of: " + name) } done <- "" }() <-done }
// 利用有缓冲通道传递数据,提高性能 package main import "fmt" func main(){ namechannel := make(chan string, 5) done := make(chan string) go func(){ names := []string {"tarik", "michael", "gopi", "jessica"} for _, name := range names { fmt.println("processing the first stage of: " + name) namechannel <- name } close(namechannel) }() go func(){ for name := range namechannel{ fmt.println("processing the second stage of: " + name) } done <- "" }() <-done }
并发等待
package main import ( "fmt" "sync" ) func main() { var wg sync.waitgroup for i := 0; i < 10; i++ { // 遍历一次,增加一次计数 wg.add(1) go func(){ fmt.println("hello world") // 执行一次,减少一次计数 wg.done() }() } // 等待计数归零,结束程序 wg.wait() }
// 利用通道等待 package main import ( "time" "fmt" ) func main() { channel := make(chan string) go func() { names := []string{"jack", "mike", "john", "kitty"} for _, name := range names { time.sleep(time.second) fmt.println(name) // channel <- name } // 遍历完毕向通道发送数据,告诉main routine已执行完毕 channel <- "" }() // main routine收到数据,退出程序 // 因为只是为了同步,不需要通道中的数据,所以将数据抛弃 <-channel }
选择并发结果
package main import ( "time" "fmt" ) func main() { channel1 := make(chan string) channel2 := make(chan string) go func(){ time.sleep(1*time.second) channel1 <- "hello from channel1" }() go func(){ time.sleep(1 * time.second) channel2 <- "hello from channel2" }() var result string // select随机选择满足条件的case select { case result = <-channel1: fmt.println(result) case result = <-channel2: fmt.println(result) } }
上一篇: jquery漂浮在网页右侧的qq在线客服插件示例代码学习
下一篇: 排序时间复杂度对比