返回顶部
首页 > 资讯 > 后端开发 > GO >关闭通道以避免超时
  • 590
分享到

关闭通道以避免超时

2024-04-04 23:04:10 590人浏览 独家记忆
摘要

对于一个golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《关闭通道以避免超时》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起

对于一个golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《关闭通道以避免超时》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起来吧,否则需要时就找不到了!

问题内容

我有一个小型 Go 程序,它每个周期(1 秒)都会发出多个请求。我正在尝试同时提出这些请求。我想计算并记录一次成功请求的数量,然后继续。如果请求没有及时完成,我不想阻止主代码。

下面的代码实现了这一点,但我不相信我正确地关闭了并发请求中的通道。因为任何错过截止日期的请求仍会使用前一个刻度进行记录。我还相信主函数中的代码会阻塞等待并发请求完成。我尝试将 close(ch) 移动到我的选择中的超时情况内,但这会导致“在关闭通道上发送”错误。

我的理解是,使用带有截止日期的上下文(可能在我的主代码中设置)可能是一个解决方案,但我正在努力理解它们,我想知道是否还有其他我可以尝试的方法。

注意:concurrentreqs 中的超时故意设置得很低,因为我是在本地测试的。

package main

import (
    "fmt"
    "time"
    "net/Http"
)

type response struct {
    num int
    statusCode int
    requestDuration time.Duration
}

func singleRequest(url string, i int, tick int) response {
    start := time.Now()
    client := http.Client{ Timeout: 100 * time.Millisecond }

    resp, _ := client.Get(url)
    fmt.Printf("%d: %d\n", tick, i)

    defer resp.Body.Close()

    return response{statusCode: int(resp.StatusCode), requestDuration: time.Since(start)}
}

func concurrentReqs(url string, reqsPerTick int, tick int) (results []response){
    ch := make(chan response, reqsPerTick)
    timeout := time.After(20 * time.Millisecond) // deliberately low
    results = make([]response, 0)

    for i := 0; i < reqsPerTick; i++ {
        go func(i int, t int) {
            ch <- singleRequest(url, i, tick)
        }(i, tick)
    }

    for i := 0; i < reqsPerTick; i++ {
        select {
        case response := <- ch:
            results = append(results, response)
        case <- timeout:
            return
        }
    }
    close(ch)

    return
}

func main() {
    var url string = "http://end-point.svc/req"

    c := time.Tick(1 * time.Second)
    for next := range c {
        things := concurrentReqs(url, 100, next.Second())
        fmt.Printf("%s: Successful Reqs - %d\n", int(next.Second()), len(things))
    }
}


解决方案


我建议使用带有超时的上下文来取消和超时。另外,我认为使用等待组和互斥保护的结果写入可以通过消除第二个循环来帮助简化。

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "sync"
    "time"
)

type response struct {
    num             int
    statusCode      int
    requestDuration time.Duration
}

func singleRequest(ctx context.Context, url string, i int, tick int) (response, error) {
    start := time.Now()

    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
    if err != nil {
        return response{requestDuration: time.Since(start)}, err
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return response{requestDuration: time.Since(start)}, err
    }

    fmt.Printf("%d: %d\n", tick, i)

    defer resp.Body.Close()

    return response{statusCode: int(resp.StatusCode), requestDuration: time.Since(start)}, nil
}

func concurrentReqs(url string, reqsPerTick int, tick int) (results []response) {
    mu := sync.Mutex{}
    results = make([]response, 0)

    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Millisecond)
    defer cancel()

    wg := sync.WaitGroup{}
    for i := 0; i < reqsPerTick; i++ {
        wg.Add(1)
        go func(i int, t int) {
            defer wg.Done()
            response, err := singleRequest(ctx, url, i, tick)
            if err != nil {
                log.Print(err)
                return
            }
            mu.Lock()
            results = append(results, response)
            mu.Unlock()
        }(i, tick)
    }

    wg.Wait()

    return results
}

func main() {
    var url string = "http://end-point.svc/req"

    c := time.Tick(1 * time.Second)
    for next := range c {
        // You may want to wrap this in a goroutine to make sure tick is not skipped.
        // Otherwise if concurrentReqs takes more than a tick time for whatever reason, a tick will be skipped.
        things := concurrentReqs(url, 100, next.Second())
        fmt.Printf("%s: Successful Reqs - %d\n", int(next.Second()), len(things))
    }
}

到这里,我们也就讲完了《关闭通道以避免超时》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注编程网公众号,带你了解更多关于的知识点!

您可能感兴趣的文档:

--结束END--

本文标题: 关闭通道以避免超时

本文链接: https://lsjlt.com/news/595941.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 关闭通道以避免超时
    对于一个Golang开发者来说,牢固扎实的基础是十分重要的,编程网就来带大家一点点的掌握基础知识点。今天本篇文章带大家了解《关闭通道以避免超时》,主要介绍了,希望对大家的知识积累有所帮助,快点收藏起...
    99+
    2024-04-04
  • golang 通道关闭
    golang 通道关闭Go是一种受欢迎的编程语言,特别适合用来编写网络应用程序和高并发应用程序。其中,通道是一种Go语言中十分重要的并发机制,它旨在实现多个goroutine之间的安全通信和同步。在使用通道时,通道的关闭是一个常见的操作。为...
    99+
    2023-05-16
  • golang 通道不关闭
    在Golang中,通道是一种非常有用的数据结构,可以在协程之间安全地传递数据。一个通道可以被关闭,以让接收方知道数据已经全部传递完毕。然而,在某些情况下,不关闭通道可能是更好的选择。首先,让我们看一下为什么关闭通道可能有帮助。当我们发送数据...
    99+
    2023-05-15
  • golang怎么关闭通道
    Golang是一门流行的编程语言,专注于处理并发。在Golang中,通道是一种重要的并发机制,用于在不同的goroutine之间进行有效的通信。通道可以用于发送和接收数据,并且具有一些其他非常有用的功能。在使用Golang的通道时,开发人员...
    99+
    2023-05-14
  • golang如何将通道关闭
    本篇内容主要讲解“golang如何将通道关闭”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“golang如何将通道关闭”吧!在golang中,可以使用close()函数来关闭通道,语法“close...
    99+
    2023-07-05
  • golang怎么关闭channal(通道)
    Golang是一个高效、强类型、并发支持的编程语言,其中的channel作为Golang的并发编程机制之一,有着非常重要的作用。在使用channel时,为了保证程序的健壮性和性能,合理地使用channel的关闭机制十分重要。本文将介绍Gol...
    99+
    2023-05-14
  • go测试10m后如何避免超时
    php小编草莓为大家带来了关于"Go测试10m后如何避免超时"的解答。在进行Go语言的测试过程中,经常会遇到超时的问题,特别是在处理大量数据的情况下。本文将介绍一些避免超时的方法,帮助...
    99+
    2024-02-11
    go语言
  • golang 关闭通道怎么实现
    Golang是一种流行的高效编程语言,它的并发特性是该语言最大的特点之一。在Golang中,通道(channel)是一种重要的并发原语,它是一种可以在两个或多个goroutines之间传递数据的对象。在使用通道时,关闭通道是一种常见的操作。...
    99+
    2023-05-14
    Golang
  • Worker Pool并发模式中何时关闭结果通道?
    目前编程网上已经有很多关于Golang的文章了,自己在初次阅读这些文章中,也见识到了很多学习思路;那么本文《Worker Pool并发模式中何时关闭结果通道?》,也希望能帮助到大家,如果阅读完后真的...
    99+
    2024-04-04
  • golang 如何正确地关闭通道
    Golang是近年来开发人员中越来越流行的编程语言。它提供了许多方便的特性,其中一个就是通道(Channel)。通道是Golang中用于协程(Goroutine)之间通信的一种机制。通道的优点是可以保证数据交换的原子性,并且可以在多个协程之...
    99+
    2023-05-14
  • 使用通道更快地关闭 goroutine
    问题内容 我是 GO 新手,我有一个关于使用通道信号停止 goroutine 的问题。 我有一个长期运行的 goroutine(超过 1000 个)和管理器来管理它: func myT...
    99+
    2024-02-06
  • 如何关闭win7唤醒定时器避免睡眠被自动唤醒
      不知道大家是否遇到这样的奇怪问题,明明笔记本进入了睡眠状态,但是却突然自动被唤醒了,电脑明明没有在跟前,不可能是自己操作的,这到底是怎么回事呢   win7之家的分析:其实这是win7系统设置了自动唤醒定时器,这是系...
    99+
    2023-06-05
    win7 唤醒 定时器
  • Go range 解决通道死锁问题,我应该关闭通道吗?
    Golang不知道大家是否熟悉?今天我将给大家介绍《Go range 解决通道死锁问题,我应该关闭通道吗?》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希...
    99+
    2024-04-05
  • 当通道以裸返回方式返回时,该通道为零
    Golang不知道大家是否熟悉?今天我将给大家介绍《当通道以裸返回方式返回时,该通道为零》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论...
    99+
    2024-04-04
  • golang函数通信管道超时处理策略
    使用管道进行通信时,为防止管道接收端一直阻塞, golang 提供两种超时处理策略:使用 context 设置时间限制或使用 select 监听多个管道,当管道接收端没有收到数据时,这两...
    99+
    2024-05-04
    管道 超时 golang
  • Windows Server 2008关闭闲置状态的IDE通道
      正常情况下,我们在启动Windows Server 2008系统的时候,该操作系统会自动将安装在对应主机中的所有硬件全部加载成功,这个加载过程会往往会拖累系统的正常启动速度,同时也会消耗不少宝贵的系统资源;其实,安装...
    99+
    2023-05-24
    通道 状态 关闭 IDE 系统 Windows Server 我们 使用 界面 闲置
  • 关闭 golang 通道是否也会强制 goroutine 同步?
    php小编西瓜在这里为大家解答一个关于golang通道的问题:关闭golang通道是否也会强制goroutine同步?通常情况下,关闭通道不会强制goroutine同步,但关闭通道会触...
    99+
    2024-02-09
  • java线程超时自动关闭怎么实现
    在Java中实现线程超时自动关闭可以使用两种方式:使用Timer类或使用Future接口。1. 使用Timer类:```javaTi...
    99+
    2023-08-31
    java
  • java线程超时自动关闭怎么设置
    在Java中,可以使用`Thread.join(long timeout)`方法来设置线程超时自动关闭。 `Thread.join(...
    99+
    2023-10-26
    java
  • 设置服务器ssh远程连接时超时关闭的时间
    我们通过ssh远程连接服务器时,如果一段时间客户端没有使用,就会与服务器断开连接。这个断开的时间我们是可以自己的设置的。 以linux centos系统为例, 具体设置方法如下: 1、通过下面的命令编译sshd配置文件 vim /etc/s...
    99+
    2023-08-22
    服务器 ssh linux 设置ssh远程连接断开时间
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作