首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阻止goroutine执行

阻止goroutine执行
EN

Stack Overflow用户
提问于 2021-11-02 08:31:34
回答 3查看 82关注 0票数 1

我的职能如下:

代码语言:javascript
复制
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
    addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
    for {
        <-err
        time.Sleep(reconnectTimer)
        conn, _ := net.Dial(n.Network, addr)
        w <- conn
    }
}

目标是在收到来自err chan的错误时重拨连接。但我不想重拨,如果我已经拨号或在一定时间内。然而,我可能会收到很多错误,我不想阻止。

我怎么能这么做?

编辑

到目前为止,我已经实现了以下解决方案:

代码语言:javascript
复制
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
    addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
    done := make(chan bool)

    isDialing := false

    for {
        select {
        case <-err:
            if !isDialing {
                isDialing = true
                time.AfterFunc(reconnectTimer, func() {
                    done <- true
                })
                
            }
        case <-done:
            conn, _ := net.Dial(n.Network, addr)
            w <- conn
            isDialing = false
        }
    }
}
EN

回答 3

Stack Overflow用户

发布于 2021-11-02 08:37:36

也许您可以使用sync.WaitGroup来确保错误后只有一个调用可重拨。

票数 0
EN

Stack Overflow用户

发布于 2021-11-02 12:26:34

代码语言:javascript
复制
type Conn struct {
    conn net.Conn
    dialing bool
    mu sync.Mutex
}

func (c Conn) Dial() {
    c.mu.Lock()
    if c.dialing {
        c.mu.Unlock()
        return
    }
    c.dialing = true
    c.mu.Unlock()
    time.AfterFunc(reconnectTimer, func() {
        c.conn, _ := net.Dial(n.Network, addr)
        w <- c.conn
        c.dialing = false
    })
}

现在您可以在go例程中调用Conn.Dial()

票数 0
EN

Stack Overflow用户

发布于 2021-11-02 14:34:33

我已经有一段时间没有使用Go了,但是我尝试使用context.Contextsync.Once来实现它。不过,我让没有对进行测试。

代码语言:javascript
复制
func keepConnUp(n netAddr, w chan<- io.Writer, err chan error) {
    addr := fmt.Sprintf("%s:%d", n.Addr, n.Port)
    done := make(chan bool)

    ctx, cancel := context.WithCancel(context.Background())
    cancel() // So that ctx.Err() returns non-nil on the first try
    once := sync.Once{}

    for {
        <-err
        if ctx.Err() != nil {
            once.Do(func() {
                conn, _ := net.Dial(n.Network, addr)
                w <- conn
            })
            once = sync.Once{} // Reset once
            ctx = context.WithTimeout(reconnectTimer) // Reset context timeout
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69807356

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档