This is a creation in Article, where the information may have evolved or changed.
Golang CHAN
Chan is a very important thing in Golang, used to do goroutine communication, because the Golang program will inevitably have multiple goroutine, how to synchronize these goroutine is very important.
There are several tips for using Chan:
- First, the symbol is always
<-
read or written, such v,ok := <-c
as read, but c <- v
write.
- Second, when reading, if there is no OK, it can also be read. But if closed is also readable, there is no assignment, if you want to know if closed is OK, that is, unless Chan never shuts down, the read should be used
v,ok := <-c
instead v := <-c
of the way it is used.
- Again, it is not possible to write to closed Chan, so it is generally necessary to write with a signal of Chan (general buffer of 1), to determine whether to write or discard, with select to determine if the write is successful, or is closing the need to discard the write.
- Finally, if Chan has data after closed, OK is still true until Chan has no data to false.
Read and Write Chan
The symbol is always <-
read or written, such v,ok := <-c
as read, but c <- v
write.
make(chanint, 1)c <- 10// 写入chan// 从chan中读取
The following example determines whether Chan closes:
make(chanint, 1)c <- 10// 读取,v=10,ok=trueclose// 读取,v=0,ok=false
If you do not write it, discard it, you can use select:
c: = Make(Chan int,1)Select{ CaseC <-Ten://C was put in 10 because Chan's buffer was 1default: }Select{ CaseC <- One:default://C only 10, not one}Select{ CaseV,ok: = <-C://read out A, v=10, Ok=truedefault:}Select{ CaseV,ok: = <-C:default://No readable, go to this branch}
You can also use timeouts and the like, also a Chan, to time.After(xxx)
return to Chan.
Judging closed
Read, if not OK, can also be read. But if closed is also readable, there is no assignment, if you want to know if closed is OK, that is, unless Chan never shuts down, the read should be used v,ok := <-c
instead v := <-c
of the way it is used.
make(chanint, 1)c <- 10close// c=10,读取出来一个// c=0,实际上没有读出来,但是判断不了
make(chanint, 1)c <- 10close// c=10,ok=true,读取出来一个// c=0,ok=false,实际上没有读出来
Write to Chan
It is not possible to write to closed Chan, so it is generally necessary to write with a signal of Chan, to determine whether to write or discard, to use Select to determine if the write was successful, or to discard the write if it is shutting down.
typeTcplistenersstruct{ConnsChan*net. Tcpconn closingChan BOOLWait *sync. Waitgroup}funcNewtcplisteners (Addrs []string) (v *tcplisteners, err error) {v = &tcplisteners{Addrs:addrs, Conns: Make(Chan*net. Tcpconn), Closing: Make(Chan BOOL,1), wait: &sync. waitgroup{},}return}//Listen at Addrs format as NETOWRK://LADDR, for example,//tcp://:1935, tcp4://:1935, tcp6://1935, tcp://0.0.0.0:1935func(v *tcplisteners) Listentcp () (err error) { for_, Addr: =RangeV.addrs {vs: = strings. Split (addr,"://") network, Laddr: = vs[0], vs[1]ifL, Err: = Net. Listen (Network, LADDR); Err! =Nil{return Nil, err}Else{v.listeners =Append(V.listeners, L. (*net). TcpListener)}} v.wait.add (Len(v.listeners)) forI, L: =Rangev.listeners {addr: = V.addrs[i]Go func(L *net. TcpListener, addrstring) {deferV.wait.done () for{varConn *net. TcpconnifConn, err = L.accepttcp (); Err! =Nil{return}Select{ CaseV.conns <-Conn: Casec: = <-v.closing:v.closing <-C Conn. Close ()}}} (L, addr)}return}func(v *tcplisteners) Accepttcp () (C *net. Tcpconn, err Error) {varOkBOOL ifC,ok = <-V.conns;!ok {return Nil, listenerdisposed}return}func(v *tcplisteners) Close () (err error) {//unblock all listener internal goroutinesV.closing <-true //Interrupt all listeners. for_, V: =Rangev.listeners {ifr: = V.close (); r! =Nil{err = R}}//wait for all listener internal Goroutines to quit.V.wait.wait ()//clear the closing signal._ = <-v.closing//Close channels to unblock the user goroutine to Accepttcp () Close(V.conns)return}
This will not cause an error when the listener is closed without causing listentcp goroutine to write to the closed Chan.
Closed Chan
If Chan has data after closed, OK is still true until Chan has no data to false.
make(chanint, 1)c <- 10close// v=10,ok=true,虽然c关闭了,但是有数据,ok依然是true// v=0,ok=false,读失败了。