go-并发编程
通道基础使用
package main
import "fmt"
func main() {
cq := make(chan string, 2)
cq <- "hello-world1"
cq <- "hello-world2"
msg1 := <-cq
msg2 := <-cq
fmt.Println(msg1, msg2)
}
阻塞和流程控制
package main
import (
"fmt"
"time"
)
func pinger(c chan string) {
t := time.NewTicker(1 * time.Second)
for {
c <- "ping"
<-t.C
}
}
func main() {
messages := make(chan string)
go pinger(messages)
for {
/*
msg 会阻塞住,直到通道messages有消息发给它,才会继续执行下一行
而上面的pinger函数,每间隔1秒会写入通道messages一条数据
通道里只能存放一条数据,边写入边消费
*/
msg := <-messages
fmt.Println(msg)
}
}
并发探测网址访问时间
package main
import (
"fmt"
"net/http"
"os"
"time"
)
func responseTime(url string, c chan string) {
start := time.Now()
res, err := http.Get(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer res.Body.Close()
elapsed := time.Since(start).Seconds()
c <- fmt.Sprintf("%s took %v seconds \n", url, elapsed)
}
func main() {
c := make(chan string)
urls := make([]string, 3)
urls[0] = "https://www.baidu.com/"
urls[1] = "https://www.gov.uk/"
urls[2] = "http://www.gouvernement.fr/"
for _, u := range urls {
go responseTime(u, c)
}
timeout := time.After(300 * time.Millisecond)
for i := 1; i <= len(urls); i++ {
select {
case res := <-c:
fmt.Println(res)
case <-timeout:
fmt.Println("timeout reached")
return
}
}
}