使用 select 实现 goroutine 超时

虽然携程是Go语言中一个新的概念,嗯,但它本质上依然是属于多线程。超时机制是多线程中是一个非常重要的保障程序的鲁棒性的一个措施;错误是很难预估的,在多线程中更为显著,更容易出现难以预料的错误。

  • 一个异常场景

在go语言中使用channel时需要小心,比如这个用法

i := <-ch

不出问题的话这个是一个很简单的,从ch中读取数据到i中。

但如果ch一直没有人往ch中写数据,那么这个读取动作也就一直无法执行,结果就是这个goroutine将会一直阻塞在这里。

有些人可以说,代码仅仅是我自己使用,我技术高超,不会出现这种低级错误;但往往代码并不是孤立了,通常都会别人使用(ctrl+v 或者参考),一旦对外公开,那么难免会出现这种问题。

所以对于这个,我们需要知道如何使用超时机制保护goroutine不被一直阻塞
go的超时机制

Go语言本身并没有原生的支持超时机制,但是我们可以使用select机制,虽然它并不是专门为超时机制而设计的。

基于上面的问题,如下是一个简易的超时机制处理

timeout := make(chan bool, 1)
go func() {
    time.Sleep(1e9)
    timeout <- true
} ()

select {
    case <- ch:
        //从ch中读取数据
    case <-timeout:
        //ch一直没有数据写入,超时触发timeout
}

转自:

http://blog.csdn.net/qq_15437667/article/category/6128870

http://blog.csdn.net/qq_15437667/article/details/52961671

时间: 2024-08-27 23:41:51

使用 select 实现 goroutine 超时的相关文章

select 设置发送超时发送注意事项

//设置发送超时你只发送, 并发送足够多的数据以填满发送缓冲区, 接收端一直不接收.发送端一量满发送缓冲区就会阻塞, 如果你设置了发送超时, 超时到了它就会返回发送超时了. 在send(),recv()过程中有时由于网络状况等原因,收发不能预期进行,而设置收发超时控制: 在Linux下需要注意的是时间的控制结构是struct timeval而并不是某一整型数,以下是来自于网上一篇文章中的摘录,它是这样写的:int nNetTimeout=1000;//1秒,//设置发送超时setsockopt(

linux c中select使用技巧

1.select函数作为定时器使用    it_value.tv_sec = 0;    it_value.tv_usec = 100000:    select(1,NULL,NULL,NULL,&it_value);   上面的代码并不是立即返回而是等待100ms,可以作为定时器使用,并且准确度比sleep高.2.linux平台下select函数修改超时时间select_timeout.tv_sec = 10;select_timeout.tv_usec = 0:for(;;){ if(se

Linux学习之select

本文和大家分享的主要是linux编程中select相关内容,一起来看看吧,希望对大家学习linux有所帮助. select系统调用的的用途是:在一段指定的时间内,监听用户感兴趣的文件描述符上可读.可写和异常等事件. select 机制的优势 为什么会出现select模型? 先看一下下面的这句代码: int iResult = recv(s, buffer,1024); 这是用来接收数据的,在默认的阻塞模式下的套接字里,recv会阻塞在那里,直到套接字连接上有数据可读,把数据读到buffer里后r

select模型的原理、优点、缺点

关于I/O多路复用: I/O多路复用(又被称为“事件驱动”),首先要理解的是,操作系统为你提供了一个功能,当你的某个socket可读或者可写的时候,它可以给你一 个通知.这样当配合非阻塞的socket使用时,只有当系统通知我哪个描述符可读了,我才去执行read操作,可以保证每次read都能读到有效数据而不 做纯返回-1和EAGAIN的无用功.写操作类似.操作系统的这个功能通过select/poll/epoll之类的系统调用来实现,这些函数都可以同时 监视多个描述符的读写就绪状况,这样,**多个描

Linux下connect超时处理【总结】

1.前言 最近在写一个测试工具,要求快速的高效率的扫描出各个服务器开放了哪些端口.当时想了一下,ping只能检测ip,判断服务器的网络是连通的,而不能判断是否开放了端口.我们知道端口属于网络的应用层,因此需要用ip和端口来探测,这个时候就可以用connect来探测一下,针对TCP协议,connect函数要进行TCP三次握手,如果connect成功,则说明服务器开放了某个端口,如果connect失败,则说明服务器没有开放某个端口.而connect失败是通过超时来控制的,在规定的时间内,connec

I/O多路复用——select

系统提供select函数来实现多路复用I/O模型,select系统调用是用来让我们的程序监视多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变. select API: 1)nfds参数指定被监听的文件描述符的总数.它通常被设置为select监听的所有文件描述符中的最大值加1,因为文件描述符是从0开始计数的. 2)readfds.writefds和exceptfds参数都是输入输出型参数,分别指向可读.可写和异常等事件对应的文件描述符集合.作

select、poll与epoll的优缺点

1.select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理. 缺点: 1) 单个进程可监视的fd数量被限制. 2) 需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大. 3) 对fd进行扫描时是线性扫描.fd剧增后,IO效率较低,因为每次调用都对fd进行线性扫描遍历,所以随着fd的增加会造成遍历速度慢的性能问题 4)select() 函数的超时参数在返回时也是未定义的,考虑到可移植性,每次在超时之后在下一次进入到sel

select/poll/epoll 对比

首先还是来看常见的select和poll.对于网络编程来说,一般认为poll比select要高级一些,这主要源于以下几个原因: poll() 不要求开发者计算最大文件描述符加一的大小. poll() 在应付大数目的文件描述符的时候速度更快,因为对于select()来说内核需要检查大量描述符对应的fd_set 中的每一个比特位,比较费时. select 可以监控的文件描述符数目是固定的,相对来说也较少(1024或2048),如果需要监控数值比较大的文件描述符,就算所监控的描述符很少,如果分布的很稀

【转】阻塞模式下的超时等待

http://www.cnblogs.com/khler/archive/2010/10/27/1863005.html 网上到处流传着“妙用select函数”实现超时等待的帖子,虽然不失为一种可选做法,但总有些不符合业务需要的前提条件,比如必须为非阻塞模式,select的文件描述符必须小于系统限制(一般是32)等等.但实际使用中,往往使用阻塞模式进行通讯,但又不想一直被阻塞,比如recv函数,如果等待指定时间接收不到信息,就认为超时. 使用setsockopt函数就可以达到此效果,下面一段文字