go是用于创建协徎/线程的,go中没有线程一说
chan是用于做阻塞操作的
通过它可以实现子线程结束以后才能主线程结束,类似于java中的join关键字
创建:

go func(){
	xxx
}

阻塞:

go func(ch chan int){
	xxx
	ch<-1
}
//结束掉阻塞
<-ch

示例:

//web服务器
package main 
 
import (
	"fmt"
	"log"
	//"net"
	"net/http"
	//"net/rpc/jsonrpc"
	//"os"
	//"encoding/json"
	//"bufio"
	//"time"
	//"bytes"
	//"encoding/hex"
	//"errors"
	//seelog "github.com/cihub/seelog"
	"html"
	"strconv"
	)
	
func main (){
	/*s := &http.Server{
        Addr:           ":8080",
        Handler:        myHandler,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }*/
	//
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		log.Println("请求的参数是",r.URL.String())
        fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
		r.ParseForm()
		log.Println("请求的参数是",r.Form)
		log.Println("请求的参数id是",r.FormValue("id"))
		
    })
    ch1,ch2:=make(chan int),make(chan int)
    go web(8001,ch1)
    go web(8002,ch2)
    log.Println("end...")
    //<-ch1
    //<-ch2
    //如果没有取出的操作,就会导致这个携程结束
    <-ch1
 	<-ch2
}
func web(i int,ch chan int){
    log.Println(i)
    http.ListenAndServe(":"+strconv.Itoa(i), nil)
    //log.Fatal()
    //这里需要注意的就是这个阻塞操作,要放到函数的最后,这样才能让函数里面的代码执行
    ch<-i
    
}