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
		}
	}

}