GO中的channel使用小结
go关键字可以用来开启一个goroutine(协程))进行任务处理,而多个任务之间如果需要通信,就需要用到channel了。 func testSimple(){ intChan := make(chan int) go func() { intChan <- 1 }() value := <- intChan fmt.Println("value : ",value) } ? 上面这个简单的例子就是新开启的goroutine向intChan发送了一个1的值,那么在主线程的intChan就会收到这个值的信息。 channel类型:无缓冲和缓冲类型 intChan := make(chan int)
带缓冲的channel,是可以指定缓冲的消息数量,当消息数量小于指定值时,不会出现阻塞,超过之后才会阻塞,需要等待其他线程去接收channel处理,带缓冲的形式如下: //3为缓冲数量 intChan := make(chan int, 3) 传输struct结构数据 type Person struct { Name string Age uint8 Address Addr } type Addr { city district } /* 测试channel传输复杂的Struct数据 */ func testTranslateStruct() { personChan := make(chan Person,1) person := Person{"xiaoming",1)">10,Addr{shenzhenlonggang"}} personChan <- person person.Address = Addr{guangzhouhuadu} fmt.Printf(src person : %+v n,person) newPerson := <-personChan fmt.Printf(new person : %+v n 测试关闭channel func testClose() { ch := make(chan int,1)">5) sign := make(chan 2) go func() { for i := 1; i <= 5; i++ { ch <- i time.Sleep(time.Second) } close(ch) fmt.Println(the channel is closed) sign <- 0 }() go func() { for { i,ok := <-ch fmt.Printf(%d,%v nif !ok { break } time.Sleep(time.Second * ) } sign <- }() <-sign <-sign } ?
* 将多个输入的channel进行合并成一个channel func testMergeInput() { input1 := make(chan int) input2 := make(chan ) output := make(chan ) go func(in1,in2 <-chan out chan<- ) { { selectcase v := <-in1: out <- v in2: v } } }(input1,input2,output) go func() { 0; i < 10; i++ { input1 <- i time.Sleep(time.Millisecond * 100) } }() go func() { 20; i < 30; i++ { input2 <-case value := <-output: fmt.Println(输出:) fmt.Println(主线程退出) } ?
/* 测试channel用于通知中断退出的问题 */ func testQuit() { g := make(chan int) quit := make(chan bool) go func() { for { select { case v := <-g: fmt.Println(v) case <-quit: fmt.Println("B退出") return } } }() for i := 0; i < 3; i++ { g <- i } quit <- true fmt.Println("testAB退出") } ? 生产者消费者问题 * 生产者消费者问题 func testPCB() { fmt.Println(test PCB) intchan := make(chan ) quitChan := make(chan bool) quitChan2 := make(chan ) value := go func() { 3; i++ { value = value + intchan <- value fmt.Println(write finish,value true }() go func() { intchan: fmt.Println(read finish,v) case <-quitChan: quitChan2 <- true return } } }() <-quitChan2 fmt.Println(task is done ) } ?
这个结果输出是1,2,也可能是2,1, 也可能是2,顺序是不一定的 func testSequnse() { ch := make(chan ) go func() { v := <-ch fmt.Println(v) }() ch <- fmt.Println(2) } ? ? 上面这个输出结果是什么呢?运行一下会发现,可能是1,2,也可能是2,1, 也可能是2,顺序是不一定的,那么为什么会是这样的,我觉得因为这是两个不同的线程, channel的超时处理 检查channel读写超时,并做超时的处理 func testTimeout() { g := make(chan ) quit := make(chan g: fmt.Println(v) case <-time.After(time.Second * time.Duration(3)): quit <- 超时,通知主线程退出) } } }() { g <- i } <-quit fmt.Println(收到退出通知,主线程退出) } channel的输入输出类型指定 指定channel是输入还是输出型的,防止编写时写错误输入输出,指定了的话,可以在编译时期作错误的检查 func testInAndOutChan() { ch := make(chan ) //输入型的chan是这种格式的:inChan chan<- int,如果换成输出型的,则编译时会报错 go func(inChan chan<- { inChan <-500) } quit <- quit <- }(ch) go func(outChan <-chan outChan: fmt.Println(print out value : quit: fmt.Println(收到退出通知,退出 } } }(ch) <-) } ?
测试通过channel来控制最大并发数,来处理事件 func testMaxNumControl() { maxNum := limit := make(chan for i:=0; i<100; i++{ fmt.Println(start worker : go func(i ) { fmt.Println(do worker start: 20do worker finish: limit if i == 99完成任务) quit <- } }(i) } <-收到退出通知,主程序退出) } ?
监听中断信号的channel func testSignal() { quit := make(chan os.Signal) signal.Notify(quit,os.Interrupt) go func() { time.Sleep(time.Second * ) number := ; { number++ println(number : 按Ctrl+C可退出程序) <- quit fmt.Println(主程序退出) } ? channel实现同步控制,生产者消费者模型 同步控制模型,生产者模型 var lockChan = make(chan var remainMoney = 1000 func testSynchronize() { quit := make(chan bool,1)">{ money := (rand.Intn(12) + 1) * go testSynchronize_expense(money) time.Sleep(time.Millisecond * time.Duration(rand.Intn())) } quit <- }() go func() { go testSynchronize_gain(money) time.Sleep(time.Millisecond * time.Duration(rand.Intn( }() <- quit <- quit fmt.Println() } func testSynchronize_expense(money ) { lockChan <- 0 if(remainMoney >= money){ srcRemainMoney := remainMoney remainMoney -= money fmt.Printf(原来有%d,花了%d,剩余%dnelse{ fmt.Printf(想消费%d钱不够了,只剩%dn lockChan } func testSynchronize_gain(money srcRemainMoney := remainMoney remainMoney +=<- lockChan } ? --------------------- (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |