go语言并发goroutine和channel

goroutine 是 go语言里的轻量级线程,仅仅利用 go 就能立刻起一个新线程。多线程之间的同步问题,在 go语言 中可以使用 channel 作为同步的工具。通过 channel 通道可以实现两个 goroutine 之间的通信。创建通道的方法使用make函数,如:make(chan 类型,num),这里的第二个参数就是要创建的通道数目,写入通道用:通道名字<-要写入的数值,从通道读取数据用:返回值<-通道名字

package main

import (
    "fmt"
    "time"
)
func fun1(tc chan int) {
    time.Sleep(10000 * time.Millisecond) //延时10秒
    fmt.Println("线程func1结束")
    tc<-1 //向通道里写入一个数据1

    close(tc)//关闭通道并不会丢失里面的数据,只是让读取通道数据的时候不会读完之后一直阻塞。
}
func fun2(tc chan int) {
    time.Sleep(5000 * time.Millisecond)//延时5秒
    fmt.Println("线程func2结束")
    tc<-2 //向通道里写入一个数据2
}
func main() {
    c:=make(chan int,2)
    go fun1(c)
    go fun2(c)
    fmt.Println("等待2个线程执行...")
    for rt:= range c {
        fmt.Println("等待到线程结束:",rt)
    }
}

可以看到,通过range遍历通道的值后,会依次读取写入通道的值。在最后close关闭通道后,range遍历就会停止。

这里,再把上边例子修改下:

package main

import (
    "fmt"
	"time"
)

func fun1(tc chan int) {
	fmt.Println("线程func1开始写入管道")
	tc<-1
	tc<-1	
	fmt.Println("线程func1结束")
}
func fun2(tc chan int) {
	time.Sleep(2000 * time.Millisecond)//延时3秒
	fmt.Println("线程func2开始写入管道")	
	tc<-2
	tc<-2	
	fmt.Println("线程func2结束")
	close(tc) //关闭通道,读取通道将退出
}

func main() {
	c:=make(chan int,2)
	go fun1(c)
	go fun2(c)
	fmt.Println("等待2个线程执行...")
	time.Sleep(6000 * time.Millisecond) //延时6秒
	for rt:= range c {
		fmt.Println("等待到线程结束:",rt)
	}
}

可以看到,这里是主程序开启2个线程后,先等待6秒。第1个线程先依次向2个管道写入数值,然后退出。而第2个线程等待3秒后开始写入管道,不过这时主程序还没从管道里读取,所以线程2是阻塞在等待。当主程序等待时间结束,开始从管道里依次读取后,线程2就可以写入管道了,在线程2一开始写入,主程序就能立即读取到。最后线程2调用close关闭管道,主程序就从遍历通道过程中结束了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值