当前位置: 首页 > news >正文

目前做哪个网站致富东莞工作装制作

目前做哪个网站致富,东莞工作装制作,重庆今天新闻事件,中国域名根服务器目录 Golang 并发 Channel的用法1. channel 的创建2. nil channel读写阻塞示例close示例 3. channel 的读写4. channel 只读只写5. 关闭channelchannel关闭后#xff0c;剩余的数据能否取到读取关闭的channel#xff0c;将获取零值使用ok判断#xff0c;是否关闭使用for-ran… 目录 Golang 并发 Channel的用法1. channel 的创建2. nil channel读写阻塞示例close示例 3. channel 的读写4. channel 只读只写5. 关闭channelchannel关闭后剩余的数据能否取到读取关闭的channel将获取零值使用ok判断是否关闭使用for-range退出使用close(ch)关闭所有下游协程 6. 当函数传递channel时是传递的引用还是值参考 Golang 并发 Channel的用法 1. channel 的创建 ch : make(chan int)上面是创建了无缓冲的 channel一旦有 goroutine 往 channel 发送数据那么当前的 goroutine 会被阻塞住直到有其他的 goroutine 消费了 channel 里的数据才能继续运行。 ch : make(chan int, 2)上面示例中的第二个参数表示 channel 可缓冲数据的容量。只要当前 channel 里的元素总数不大于这个可缓冲容量则当前的 goroutine 就不会被阻塞住。 2. nil channel nil是pointers, interfaces, maps, slices, channels 和 function 类型的零值,表示未初始化值。nil不是未定义状态它本身就是值。error是接口类型因此error变量可以为nil但string不能为nil。 下面我们看下nil 通道有什么特点空通道对操作的反应如下 从空通道读、写会永远阻塞关闭通道会终止程序(panic) 空通道是一种特殊通道总是阻塞。对比非空已关闭的通道仍然可以进行读取并能够读取对应类型的零值但对于已关闭的通道发送信息会终止程序。 一般 nil channel 用在 select 上让 select 不再从这个 channel 里读取数据 读写阻塞示例 示例如下 func TestNil(t *testing.T) {c : make(chan int)go sendIntegers(c)addIntegers(c) }func addIntegers(c chan int) {sum : 0t : time.NewTimer(time.Second * 5)for {select {case input : -c:sum sum inputfmt.Println(addIntegers , input : strconv.Itoa(input) , sum : strconv.Itoa(sum))case -t.C:c nilfmt.Println(addIntegers , nil channel , sum : strconv.Itoa(sum))}} }func sendIntegers(c chan int) {for {time.Sleep(time.Second * 1)c - rand.Intn(100)} } 输出如下 RUN TestNil addIntegers , input : 81 , sum : 81 addIntegers , input : 87 , sum : 168 addIntegers , input : 47 , sum : 215 addIntegers , input : 59 , sum : 274 addIntegers , nil channel , sum : 274 panic: test timed out after 30s此示例会一直阻塞下去addIntegers是程序的主协程会一直阻塞下去sendIntegers是子协程同样会一直阻塞下去。 其中输出中的panic是单元测试的Test引发的异常不需要考虑在内。 close示例 func TestCloseNil(t *testing.T) {c : make(chan int)go writeChannel(c)num : -cfmt.Println(main goroutine , read num : strconv.Itoa(num))c nilfmt.Println(main goroutine , to close channel .)close(c)time.Sleep(time.Second * 10)}func writeChannel(c chan int) {fmt.Println(writeChannel goroutine , running ...)c - 1 }输出如下 RUN TestCloseNil writeChannel goroutine , running ... main goroutine , read num : 1 main goroutine , to close channel . --- FAIL: TestCloseNil (0.00s) panic: close of nil channel [recovered]panic: close of nil channel关闭nil通道会引起程序panic 3. channel 的读写 写操作 ch : make(chan int) ch - 1读操作 data - ch当我们不再使用 channel 的时候可以对其进行关闭 close(ch)如果 channel 关闭继续读取关闭后的 channel不会产生 pannic还是可以读到数据将得到零值即对应类型的默认值。 为了能知道当前 channel 是否被关闭可以使用下面的写法来判断。 当channel关闭时ok false当channel未关闭时ok true if v, ok : -ch; !ok {fmt.Println(channel 已关闭读取不到数据)}另一种写法可以使用 for-range 使用下面的写法不断的获取 channel 里的数据直到channel关闭跳出循环执行后面的代码。 for data : range ch {// get data dosomething}4. channel 只读只写 在默认情况下管道是双向的可读可写在使用 channel 时我们还可以控制 channel 只读只写操作 声明为只写如下 var chan2 chan- int chan2 make(chan int, 3) chan2 - 20如果试着读此chan则编译报错编译错误如下 invalid operation: cannot receive from send-only channel chan2 (variable of type chan- int) compiler (InvalidReceive)声明为只读不可写否则编译报错如下 var chan3 -chan int nm2 : -chan3函数可以声明chan只读只写代码示例 // 只写操作 func send(ch chan- int, exitChan chan struct{}) {for i : 0; i 5; i {time.Sleep(time.Second * 1)ch - i}close(ch)var a struct{}exitChan - a }// 只读操作 func recv(ch -chan int, exitChan chan struct{}) {for {v, ok : -chif !ok {break}fmt.Println(recv goroutine , value : strconv.Itoa(v))}var a struct{}exitChan - a } func TestOnlyReadWrite(t *testing.T) {ch : make(chan int, 10)exitChan : make(chan struct{}, 2)go send(ch, exitChan)go recv(ch, exitChan)var total 0for _ range exitChan {totalif total 2 {break}}fmt.Println(main goroutine , 结束) }输出如下 RUN TestOnlyReadWrite recv goroutine , value : 0 recv goroutine , value : 1 recv goroutine , value : 2 recv goroutine , value : 3 recv goroutine , value : 4 main goroutine , 结束 --- PASS: TestOnlyReadWrite (5.03s)5. 关闭channel channel关闭后剩余的数据能否取到 golang channel关闭后其中剩余的数据是可以继续读取的channel关闭之后仍然可以从channel中读取剩余的数据直到数据全部读取完成。 对于关闭的channel的读写需要注意两点 如果继续向channel发送数据会引起panic如果继续读数据得到的是零值(对于int就是0)。 读取关闭的channel将获取零值 当读取已关闭的channel时如果继续读取channel获取到的是零值不会堵塞 另外即使是无缓冲的channel也将能一直获取到零值。 代码示例如下 func TestCloseDemo01(t *testing.T) {done : make(chan struct{})ch : make(chan int, 3)ch - 1ch - 2ch - 3close(ch)go func() {for {value : -ch//此处为假设判断value永远不会等于10if value 10 {break}fmt.Println(read channel , value : , value)time.Sleep(time.Second * 1)}done - struct{}{}}()select {case -done:fmt.Println(读取channel正常结束)case -time.After(time.Second * 5):fmt.Println(超时退出)} } 输出如下 RUN TestCloseDemo01 read channel , value : 1 read channel , value : 2 read channel , value : 3 read channel , value : 0 read channel , value : 0 超时退出 --- PASS: TestCloseDemo01 (5.00s)使用ok判断是否关闭 读取channel判断是否关闭 value, ok : -ch当channel关闭时okfalse当channel未关闭时oktrue 通过判断channel是否关闭当channel关闭时程序可以正常退出代码示例如下 func TestCloseDemo02(t *testing.T) {done : make(chan struct{})ch : make(chan int, 3)ch - 1ch - 2ch - 3close(ch)go func() {for {value, ok : -chif !ok {break}fmt.Println(read channel , value : , value)time.Sleep(time.Second * 1)}done - struct{}{}}()select {case -done:fmt.Println(读取channel正常结束)case -time.After(time.Second * 5):fmt.Println(超时退出)} }输出如下 RUN TestCloseDemo02 read channel , value : 1 read channel , value : 2 read channel , value : 3 读取channel正常结束 --- PASS: TestCloseDemo02 (3.03s) PASS使用for-range退出 for-range是使用频率很高的结构常用它来遍历数据range能够感知channel的关闭当channel被发送数据的协程关闭时range就会结束接着退出for循环。 它在并发中的使用场景是当协程只从1个channel读取数据然后进行处理处理后协程退出。 下面这个示例程序当通道被关闭时协程可自动退出。 func TestCloseDemo02(t *testing.T) {ch : make(chan int, 3)ch - 1ch - 2ch - 3close(ch)for v : range ch {fmt.Println(value, v)}time.Sleep(time.Second * 10) }使用close(ch)关闭所有下游协程 关闭通道可以主动通知所有协程退出的场景 当启动100个worker时只要main()执行关闭stopCh每一个worker都会都到信号进而关闭。如果main()向stopCh发送100个数据这种就低效了。 //close关闭所有子协程 func TestCloseDemo04(t *testing.T) {ch : make(chan int, 3)stopCh : make(chan struct{})for i : 1; i 6; i {worker(workerstrconv.Itoa(i), stopCh, ch)}time.Sleep(time.Second * 5)close(stopCh)time.Sleep(time.Second * 5) }func worker(workerName string, stopCh -chan struct{}, ch -chan int) {go func() {defer fmt.Println(workerName, goroutine , worker exit)// Using stop channel explicit exitfor {select {case -stopCh:fmt.Println(workerName, goroutine , Recv stop signal , return)returndefault:fmt.Println(workerName, goroutine , worker default ...)}time.Sleep(time.Second * 3)}}() }输出如下 RUN TestCloseDemo04 worker5 goroutine , worker default ... worker3 goroutine , worker default ... worker4 goroutine , worker default ... worker1 goroutine , worker default ... worker2 goroutine , worker default ... worker3 goroutine , worker default ... worker2 goroutine , worker default ... worker5 goroutine , worker default ... worker4 goroutine , worker default ... worker1 goroutine , worker default ... worker4 goroutine , Recv stop signal , return worker4 goroutine , worker exit worker2 goroutine , Recv stop signal , return worker2 goroutine , worker exit worker5 goroutine , Recv stop signal , return worker5 goroutine , worker exit worker1 goroutine , Recv stop signal , return worker1 goroutine , worker exit worker3 goroutine , Recv stop signal , return worker3 goroutine , worker exit --- PASS: TestCloseDemo04 (10.01s) PASS6. 当函数传递channel时是传递的引用还是值 golang 传递给函数chan类型时是值传递和引用传递 golang默认都是采用值传递即拷贝传递有些值天生就是指针slice、map、channel 可以看出来map和slice都是指针传递即函数内部是可以改变参数的值的。而array是数组传递不管函数内部如何改变参数都是改变的拷贝值并未对原值进行处理。 在 Go 语言中所有的函数参数传递都是值传递pass by value当将参数传递给函数时实际上是将参数的副本传递给函数。然而这并不意味着在函数内部对参数的修改都不会影响原始数据。因为在 Go 中有些数据类型本身就是引用类型比如切片slice、映射map、通道channel、接口interface和指针pointer。当这些类型作为参数传递给函数时虽然传递的是值但值本身就是一个引用。 小结 Go 语言中的参数传递总是值传递意味着传递的总是变量的副本无论是基本数据类型还是复合数据类型。由于复合数据类型如切片、映射、通道、接口和指针内部包含的是对数据的引用所以在函数内部对这些参数的修改可能会影响到原始数据。理解这一点对于编写正确和高效的Go代码至关重要。 另外即使是引用类型比如切片当长度或容量比如使用 append 函数发生变化了可能会导致分配新的底层数组。这种情况下原始切片不会指向新的数组但是函数内部的切片会。因此如果想在函数内部修改切片的长度或容量并反映到外部应该传递一个指向切片的指针。 参考 https://www.cnblogs.com/-wenli/p/12350181.htmlhttps://segmentfault.com/a/1190000017958702https://zhuanlan.zhihu.com/p/395278270https://zhuanlan.zhihu.com/p/613771870Go里面如何实现广播 https://juejin.cn/post/6844903857395335182
http://www.hkea.cn/news/14561770/

相关文章:

  • 泉州建设网站制作怎样做网络推广信任豪升网络好
  • 个人网站备案条件湖南系统开发
  • 网站建设平台 三合一wordpress衔接出错
  • 甘南网站建设公司如何做软件开发
  • app开发公司tianpinkeji济南关键词优化平台
  • 国内做音乐网站长沙有哪些正规传媒公司
  • 帮人做彩票网站专业网站建设明细报价表
  • 推荐一些外国做产品网站wordpress 链接管理员
  • 佛山市城乡住房建设局网站首页冷饮网站开发背景意义
  • 上海 建网站微信网页版网址
  • 百色网站建设公司自己做网站卖什么
  • 男女做暧网站建筑业大数据服务平台官网
  • 怎么做一个网站页面上海房产网二手房出售
  • html5 网站个人网站备案材料
  • 网站属于什么公司搜索引擎网站提交入口
  • 怎样提高网站流量沈阳网站开发公司
  • 网站更新前知道内容企业网站 设
  • 网站设计素养房山区文化活动中心有wifi吗
  • 长沙微信网站制作以下哪些是网络营销的特点
  • 怎么才能注册做网站如何建立个人网址
  • 重庆市工信部网站代理网店加盟
  • 长沙开发网站的公司哪家好上海 网站建设 案例
  • 公司内部网站怎么做金沙百度seo优化公司
  • 太原模板建站定制济南网络推广网络营销软件
  • 外贸网站推广 雅虎问答有用吗深圳昨天下午出大事
  • 苍南网站制作wordpress调用热门标签
  • 北京网站设计开发公司网站开发微盘
  • 一个做品牌零食特卖的网站中小微企业名录库
  • 网站建设对信息公开的作用网站建设便宜的公司哪家好
  • 灵宝网站制作工作室网页设计公司济南兴田德润优惠吗