21
_demo/chandemo/chan.go
Normal file
21
_demo/chandemo/chan.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c1 := make(chan string)
|
||||||
|
c2 := make(chan string, 1)
|
||||||
|
go func() {
|
||||||
|
c1 <- "ch1"
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
c2 <- "ch2"
|
||||||
|
}()
|
||||||
|
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
select {
|
||||||
|
case msg1 := <-c1:
|
||||||
|
println(msg1)
|
||||||
|
case msg2 := <-c2:
|
||||||
|
println(msg2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,7 @@ type Chan struct {
|
|||||||
len int
|
len int
|
||||||
cap int
|
cap int
|
||||||
sops *selectOp
|
sops *selectOp
|
||||||
|
sends uint16
|
||||||
close bool
|
close bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +109,9 @@ func ChanSend(p *Chan, v unsafe.Pointer, eltSize int) bool {
|
|||||||
p.mutex.Lock()
|
p.mutex.Lock()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
for p.getp != chanHasRecv && !p.close {
|
for p.getp != chanHasRecv && !p.close {
|
||||||
|
p.sends++
|
||||||
p.cond.Wait(&p.mutex)
|
p.cond.Wait(&p.mutex)
|
||||||
|
p.sends--
|
||||||
}
|
}
|
||||||
if p.close {
|
if p.close {
|
||||||
p.mutex.Unlock()
|
p.mutex.Unlock()
|
||||||
@@ -140,9 +143,13 @@ func ChanTryRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool, tryOK boo
|
|||||||
n := p.cap
|
n := p.cap
|
||||||
p.mutex.Lock()
|
p.mutex.Lock()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
tryOK = p.close
|
if p.sends == 0 || p.getp == chanHasRecv || p.close {
|
||||||
p.mutex.Unlock()
|
tryOK = p.close
|
||||||
return
|
p.mutex.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.getp = chanHasRecv
|
||||||
|
p.data = v
|
||||||
} else {
|
} else {
|
||||||
if p.len == 0 {
|
if p.len == 0 {
|
||||||
tryOK = p.close
|
tryOK = p.close
|
||||||
@@ -158,7 +165,18 @@ func ChanTryRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool, tryOK boo
|
|||||||
notifyOps(p)
|
notifyOps(p)
|
||||||
p.mutex.Unlock()
|
p.mutex.Unlock()
|
||||||
p.cond.Broadcast()
|
p.cond.Broadcast()
|
||||||
return true, true
|
if n == 0 {
|
||||||
|
p.mutex.Lock()
|
||||||
|
if p.getp == chanHasRecv {
|
||||||
|
p.cond.Wait(&p.mutex)
|
||||||
|
}
|
||||||
|
recvOK = (p.getp != chanHasRecv)
|
||||||
|
tryOK = recvOK
|
||||||
|
p.mutex.Unlock()
|
||||||
|
} else {
|
||||||
|
recvOK, tryOK = true, true
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ChanRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool) {
|
func ChanRecv(p *Chan, v unsafe.Pointer, eltSize int) (recvOK bool) {
|
||||||
|
|||||||
Reference in New Issue
Block a user