goroutine/channel(1)-创新互联
channel可以是各种数据类型:
(map类型)
(struct类型)
(接口类型)
package main
import "fmt"
type student struct {
name string
}
func main() {
var stuChan chan interface{}
//空interface类型可以是任意类型
stuChan = make(chan interface{}, 10)
stu := student{name:"stu01"}
stuChan <- &stu
var stu01 interface{}
stu01 = <- stuChan
fmt.Println(stu01)
var stu02 *student
//将stu01由interface转换为结构体类型指针
stu02, ok := stu01.(*student)
if !ok {
fmt.Println("不可以转换")
return
}
fmt.Println(stu02)
}
输出:
&{stu01}
&{stu01}
Process finished with exit code 0
channel关闭,判断:
package main
import "fmt"
func main() {
var ch chan int
ch = make(chan int, 10)
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
for {
var b int
//从chan取数据的时候第二个参数用来判断是否成功
b, ok := <- ch
if ok == false {
fmt.Println("chan is closed")
return
}
fmt.Println(b)
}
}
输出:
0
1
2
3
4
5
6
7
8
9
chan is closed
range遍历chan:
package main
import "fmt"
func main() {
var ch chan int
ch = make(chan int, 1000)
for i := 0; i < 1000; i++ {
ch <- i
}
close(ch)
for v := range ch {
fmt.Println(v)
}
}
关闭chan,goroutine同步案例:
package main
import (
"fmt"
)
func calc(taskChan chan int, resChan chan int, exitChan chan bool) {
for v := range taskChan {
flag := true
for i := 2; i < v; i++ {
if v%i == 0 {
flag = false
break
}
}
if flag {
resChan <- v
}
}
fmt.Println("exit")
//每个calc的协程(goroutine)结束后写入true到名为exitChan的chan里。代表该goroutine结束了
exitChan <- true
}
func main() {
intChan := make(chan int, 1000)
resultChan := make(chan int, 1000)
exitChan := make(chan bool, 8)
go func() {
for i := 0; i < 10000; i++ {
intChan <- i
}
close(intChan)
}()
for i := 0; i < 8; i++ {
go calc(intChan, resultChan, exitChan)
}
//等待所有计算的goroutine全部退出
go func() {
for i := 0; i < 8; i++ {
<-exitChan
fmt.Println("wait goroute ", i, " exited")
}
//8个goroutine结束后关闭resultChan管道
close(resultChan)
}()
//resultChan管道关闭后,range才能在遍历完后结束
for v := range resultChan {
fmt.Println(v)
}
}
再来个同步channel的例子:
package main
import (
"fmt"
)
func send(ch chan int, exitChan chan bool) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
exitChan <- true
}
func recv(ch chan int, exitChan chan bool) {
for {
v, ok := <- ch
if !ok {
break
}
fmt.Println(v)
}
exitChan <- true
}
func main() {
ch := make(chan int, 10)
exitChan := make(chan bool, 2)
go send(ch, exitChan)
go recv(ch, exitChan)
var total = 0
for _ = range exitChan {
total++
if total == 2 {
break
}
}
}
输出:
0
1
2
3
4
5
6
7
8
9
Process finished with exit code 0
channel的只读,只写(读函数里只准读,写函数里只准写。来进行规范,防止出错):
package main
import "fmt"
func send(ch chan<- int, exitChan chan struct{}) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
var a struct{}
exitChan <- a
}
func recv(ch <-chan int, exitChan chan struct{}) {
for {
v, ok := <-ch
if !ok {
break
}
fmt.Println(v)
}
var a struct{}
exitChan <- a
}
func main() {
var ch chan int
ch = make(chan int, 10)
exitChan := make(chan struct{}, 2)
go send(ch, exitChan)
go recv(ch, exitChan)
var total = 0
for _ = range exitChan {
total++
if total == 2 {
break
}
}
}
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
文章名称:goroutine/channel(1)-创新互联
URL链接:http://azwzsj.com/article/cchsop.html