|
|
51CTO旗下网站
|
|
移动端

10.3.4 超时和计时器

《Go语言编程入门与实战技巧》第10章并发编程,本章Go语言里的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为协程(goroutine)时,Go语言会将其视为一个独立的工作单元,这个单元会被调度到可用的逻辑处理器上执行。本节为大家介绍超时和计时器。

作者:黄靖钧来源:电子工业出版社|2018-09-23 09:50

10.3.4  超时和计时器

在之前对channel的介绍中,完全没有提到错误处理的问题,而这个问题显然是不能被忽略的。在并发编程的通信过程中,最需要处理的就是超时问题,即向channel写数据时发现channel已满,或者从channel试图读取数据时发现channel为空。如果不正确处理这些情况,很可能会导致整个goroutine锁死。

虽然goroutine是Go语言引入的新概念,但通信锁死问题已经存在很长时间了,在之前的C/C++开发中也存在。操作系统在提供此类系统级通信函数时也会考虑超时的场景,因此这些方法通常都会带一个独立的超时参数。超过设定的时间时,仍然没有处理完任务,则该方法会立即终止并返回对应的超时信息。超时机制本身虽然也会带来一些问题,比如在运行比较快的机器或者高速的网络上运行正常的程序,到了慢速的机器或者网络上运行就会出问题,从而出现结果不一致的现象,但从根本上来说,解决死锁问题的价值要远大于所带来的问题。

使用channel时需要小心,比如对于以下这个用法:

  1. :<-ch 

不出问题的话一切都正常运行,但如果出现了一个错误情况,即永远都没有人往ch里写数据,那么上述这个读取动作也将永远无法从ch中读取到数据,导致的结果就是整个goroutine永远阻塞并没有挽回的机会。如果channel只是被同一个开发者使用,那样出问题的可能性还低一些。但如果一旦对外公开,就必须考虑到最差的情况并对程序进行保护。

Go语言没有提供直接的超时处理机制,但可以利用select机制。虽然select机制不是专为超时而设计的,却能很方便地解决超时问题,因为select的特点是只要其中一个case已经完成,程序就会继续往下执行,而不会考虑其他case的情况。

基于此特性,来为channel实现超时机制:

  1. // 首先实现并执行一个匿名的超时等待函数  
  2. timeout :make(chan bool, 1)  
  3. go func() {  
  4.     time.Sleep(1e9) // 等待1秒  
  5.     timeout <- true  
  6.     }()  
  7.     // 然后把timeout这个channel利用起来  
  8.     select {  
  9.     case <-ch: 
  10.         // 从ch中读取到数据  
  11.     case <-timeout: 
  12.         // 一直没有从ch中读取到数据,但从timeout中读取到了数据  
  13. }  


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

超级网管员——网络服务

本书全面介绍了Windows Server 2003 R2中最常用的各种服务,包括域名服务、动态IP地址服务、Windows名称服务、活动目录服务、Web服务、FTP...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊