详解Golang 中的并发限制与超时控制

详解Golang 中的并发限制与超时控制

前言

该文主要讲述在 Golang 中如何控制并发数以及如何实现请求的超时控制。在实际的开发中,这两个问题是非常重要的,同时在一些性能优化场景下也会起到很大的作用。

控制并发

在 Golang 中,我们可以通过设置goroutine的数量来控制并发的数量。假设我们有一个需求,在获取照片的时候我们不希望并发数量过高,同时也不希望请求照片的过程中出现错误。我们此时可以通过使用一个带有限制并发量的队列来实现这个功能。

基本思路

我们可以先定义一个函数来获取照片,假设这个函数是 getPicture,然后我们创建一个带有固定缓存大小的 Channel,将需要获取照片的任务放进去。我们可以定义一个goroutine,并从 Channel 中取出任务。对于每个任务,我们可以将此任务的处理放入到另外一个带有一个goroutine的 Channel 中,并阻塞,等待网上获取照片,同时会使用一个计数器来记录处理的任务的数量。每当处理完一个任务时,该计数器的值会自增,最终在该 Channel 中收到所有的响应之后,我们可以将所有任务的响应放入到一个结果数组中。

示例代码

下面是一个带有并发限制的获取照片的示例代码,只会同时进行2个任务的处理。

package main

import (
    "fmt"
    "time"
)

func main() {
    start := time.Now()
    // 声明并发限制为 2 的缓存型通道
    c := make(chan int, 2)
    var urls = []string{"http://www.baidu.com", "http://www.sina.com", "http://www.sohu.com", "http://www.qq.com", "http://www.taobao.com", "http://www.tmall.com", "http://www.jd.com", "http://www.163.com"}
    responses := []string{}

    // 开始处理任务
    for _, url := range urls {
        // 将任务放到 Channel 中,并开启 goroutine 进行处理
        c <- 1
        go func(url string) {
            // 处理任务
            response := fmt.Sprintf("Url: %s, Result: XXX", url)
            responses = append(responses, response)

            // 执行完任务后,从 Channel 中取出标记
            <-c
        }(url)
    }

    // 等待任务完成
    for {
        if len(c) == 0 {
            break
        }
    }

    // 处理所有任务响应,仅为示例,执行一个简单的输出
    for _, response := range responses {
        fmt.Println(response)
    }

    fmt.Printf("Elapsed time: %s", time.Since(start))
}

超时控制

在 Golang 中,我们也可以通过一个 context 变量和 time 包配合来实现请求超时的控制。下面我们将通过一个示例来讲解如何实现该功能。

基本思路

我们假设我们要请求一个 API 以获取数据,但是由于网络可能出现问题或 API 服务不可用等情况,我们不能保证所有请求都能及时得到响应。另外,我们也不希望等待所有请求都超时后才能返回结果。因此,我们可以使用上下文和超时作为 API 请求的两个主要参数。我们可以使用context 模块来控制请求的生命周期,而 time.AfterFunc() 可以用于设置超时定时器,一旦定时器被触发时,将会导致 API 请求取消。

示例代码

下面是一个带有超时控制的 API 请求示例。

package main

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

func main() {
    // 创建上下文
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    tr := &http.Transport{}
    client := &http.Client{Transport: tr}

    // 发送请求
    req, _ := http.NewRequest("GET", "http://httpbin.org/get", nil)
    req = req.WithContext(ctx)

    // 设置超时定时器
    ch := make(chan int, 1)
    go func() {
        time.Sleep(3 * time.Second)
        ch <- 1
    }()

    // 等待 API 请求响应
    select {
    case <-ch:
        fmt.Println("API请求超时")
    case <-ctx.Done():
        fmt.Println("API请求取消")
        return
    default:
        res, err := client.Do(req)
        if err != nil {
            fmt.Println(err.Error())
            return
        }

        defer res.Body.Close()

        fmt.Println("API请求成功")
    }
}

在上面的示例中,我们首先创建一个上下文变量,然后使用一个 http.Client 对象初始化一个 GET 请求。接着我们创建一个带有指定超时时间的 Channel,并使用定时器开启一个子线程等待超时时间到达。最后,我们在一个 select 语句中等待 API 请求响应返回,一旦定时器到期,我们将会收到一个来自超时定时器的响应,根据响应来取消 API 请求。

结尾

本篇文章主要讲解了 Golang 中如何控制并发以及如何实现请求的超时控制。这些方案都是非常重要的,可以帮助我们更好地定制化和优化在大型系统中的性能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Golang 中的并发限制与超时控制 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 异步/多线程/任务/并行编程之一:如何选择合适的多线程模型?

    选择合适的多线程模型需要考虑以下几个因素: 需要处理的任务类型 资源限制(CPU、内存等) 代码可读性、可维护性、可重用性 开发效率和代码复杂度 根据不同的需求和限制,可以选择以下多线程模型: 线程池模型 Future/Promise模型 Actor模型 数据流模型 线程池模型: 线程池模型是最基础的多线程模型之一,通过创建一定数量的线程来处理任务队列中的任…

    多线程 2023年5月17日
    00
  • Java 多线程并发编程提高数据处理效率的详细过程

    Java 多线程并发编程是提高数据处理效率的重要手段。以下是详细的攻略: 什么是多线程并发编程 多线程并发编程指一个程序同时启动多个线程,每个线程执行不同的任务。在多线程并发编程中,线程同步和锁机制非常重要。线程同步是多个线程保证数据同步和互斥访问的机制,锁机制用于控制对共享资源的访问。 多线程并发编程的好处 多线程并发编程可以大大提高数据处理效率,特别是在…

    多线程 2023年5月16日
    00
  • Java并发工具辅助类代码实例

    针对“Java并发工具辅助类代码实例”的完整攻略,我们将从以下几个方面进行讲解: 什么是Java并发工具类? Java并发工具类的分类? Java并发工具类的使用方法? Java并发工具类的示例说明。 1. 什么是Java并发工具类? Java并发工具类是Java中提供的一些辅助类,用于实现线程安全的并行计算和多线程操作。这些工具类可以大大简化多线程编程的复…

    多线程 2023年5月17日
    00
  • C++高并发内存池的实现

    C++高并发内存池是一个常见的性能优化手段,能够优化内存分配和释放的性能,并且在高并发场景下表现出色。本文将详细讲解C++高并发内存池的实现,包括内存池的设计思路、具体实现方式以及使用样例。下面进入正文。 一、设计思路 C++高并发内存池的设计需要考虑以下几个方面: 内存块的分配和释放:内存池需要维护一个内存块池,用于分配和释放内存块,在高并发情况下需要避免…

    多线程 2023年5月17日
    00
  • 易语言实现双线程的方法解析

    易语言实现双线程的方法解析 什么是双线程 双线程是指在一个程序中,可以有两个或以上的线程同时运行。在易语言编程中,实现双线程可以大大提高程序的效率。 实现双线程的方法 在易语言中,实现双线程的方法有两种:使用EasyThread库和使用Win32API。 使用EasyThread库 EasyThread库是易语言中自带的一个多线程库,通过它可以实现简单的多线…

    多线程 2023年5月17日
    00
  • 你的服务器IIS最大并发数有多少?

    回答: 你的服务器IIS最大并发数有多少? IIS是运行在Windows上的一个Web 服务器,它的最大并发数是指同时可以处理的请求数量。那么,如何查看你的服务器IIS的最大并发数呢?以下是方法: 方法一:在IIS管理器中查看 打开IIS管理器,选择你的站点。 在站点主窗口中,双击“限制”,在“方法”下选择“连接限制”。 在“连接限制”对话框中,可以看到“最…

    多线程 2023年5月16日
    00
  • 浅析PHP中Session可能会引起并发问题

    下面是详细讲解“浅析PHP中Session可能会引起并发问题”的完整攻略。 什么是Session Session是Web开发中常用的一种状态管理技术,用于在服务器端存储用户的状态信息,包括登录状态、购物车信息等。Session的工作方式是通过生成一个唯一的标识符(session_id)来标记用户访问的状态信息,然后将session_id保存在浏览器的Cook…

    多线程 2023年5月16日
    00
  • 彻底搞懂Java多线程(二)

    下面详细讲解一下“彻底搞懂Java多线程(二)”的完整攻略。 1. 线程的基本操作 在Java中,线程是通过Thread类来创建和启动的。创建线程的过程就是创建一个Thread对象,然后通过调用该对象的start()方法来启动线程,如下所示: Thread thread = new Thread(); thread.start(); 默认情况下,新线程会与当…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部