为了账号安全,请及时绑定邮箱和手机立即绑定

阻止 goroutine 执行

阻止 goroutine 执行

Go
互换的青春 2022-10-10 18:58:56
我有一个功能如下: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. 但是,如果我已经在拨号或在某个时间段内,我不想重拨。但是,我可能会收到很多我不想阻止的错误。我怎么能那样做?编辑到目前为止我已经实施的解决方案: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        }    }}
查看完整描述

3 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

context.Context自从我从事 Go 工作以来已经有一段时间了,但我尝试使用and让它工作sync.Once。我还没有测试过这个。


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

        }

    }

}




查看完整回答
反对 回复 2022-10-10
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

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

    })

}

现在你可以调用Conn.Dial()一个 goroutine


查看完整回答
反对 回复 2022-10-10
?
慕桂英546537

TA贡献1848条经验 获得超10个赞

也许您可以使用sync.WaitGroup它来确保在错误后只有一次重拨呼叫。



查看完整回答
反对 回复 2022-10-10
  • 3 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信