golang中实现select超时机制

对于c/c++开发来说,有和os最为贴切的api可以用,例如
带超时机制的互斥锁

       #include <pthread.h>
       #include <time.h>

       int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,
           const struct timespec *restrict abstime);

带超时机制的epoll

       #include <sys/epoll.h>

       int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
       int epoll_pwait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout,
                      const sigset_t *sigmask);

等。

但是对于golang这样一个新的语言来说,需要完善的地方还有一些。例如一些开源组件的重写,cordis、mysql等用golang重写,有些api确实不那么完善。

对于多路复用来说,不可能一直等待信号。万一发信号的死掉了,经常岂不是傻傻的等着了吗。所以有超时机制。
golang 虽然没有原生的api可以满足条件,但是可以组合一下,在应用层实现这种功能。(这也符合linux微内核的设计思想)

package main
import (
        "fmt"
        "time"
        "strconv"
)
func main() {
        ch := make(chan string)
        quit := make(chan bool)
        go func() {
                for i := 0; i < 10; i++ {
                        ch <- strconv.Itoa(i)
                        time.Sleep(time.Second)
                }
        }()

        go func() {
                timeout := time.After(time.Second * 2)	// 注意,定时器必须放在select外面
                flagrun := true
                for ; flagrun == true ; {
                        select {
                        case <-timeout:
                                fmt.Println("2 second timout,then send one message to channel quit ,and exit for loop and goroutine")
                                flagrun = false
                                quit <- true
                        case str := <-ch:
                                fmt.Println("string: ", str)
                        }
                }
        }()
        <-quit
        close(ch)
        close(quit)
        fmt.Println("endof process")
}
发布了85 篇原创文章 · 获赞 71 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/jacky128256/article/details/104659558