zoukankan      html  css  js  c++  java
  • golang _下划线占位符代替需要释放的资源的问题

    golang中_有两种作用,一种用在import中,比如这样

    import _ "github.com/go-sql-driver/mysql"

    表示并不需要导入整个包,只是执行这个包里面所有的init函数。另一个作用就是作为变量的占位符,比如req, _ := http.NewRequest(....),这里http.NewRequest返回的是两个参数,但是如果我并不需要用到error参数时,就可以用_线代替。

    但是这里就有一种特殊情况了,例如,response, err := Client.Do(req),这种场景还是比较常见的,就是发起一个http请求时,当我不关心response时,是否可以用_代替而不接收这个参数呢?

    答案是不可以的。因为这里发起http请求时,已经打开了一个tcp连接,如果不显式的调用 response.Body.Close()的话,是不会自动断开tcp连接的,尽管golang的gc已经完成了内存的回收,但是仍然不会关闭tcp连接。下面测试过程:这里测试请求了baidu,然后用_代替response参数,用tcpdump进行抓包

    代码如下:

    package main
    
    import (
        log "ad-service/alog"
        "net/http"
        "strings"
        "time"
    )
    
    func send() {
        req, err := http.NewRequest("GET", "http://baidu.com", strings.NewReader(""))
        if err != nil {
            log.Error(err)
            return
        }
        client := http.Client{}
        _, err := client.Do(req)
        //resp, err := client.Do(req) // 不调用Close
        if err != nil {
            log.Error(err)
            return
        }
        //defer resp.Body.Close()  // 不调用Close
    }
    
    func main() {
        send()
        time.Sleep(1000 * time.Second) // 保持进程一直运行,当进程停止时会被操作系统强行回收资源
    }
    View Code

    抓包结果:

    可以看到请求结束之后30秒依然没有发送FIN包来断开连接。这个时候我手动Ctrl+C终止进程后:

    正常进行了四次挥手。打开了文件都要关闭大家都知道,但是这里特殊的地方在于golang中使用_下划线并不是靠谱的。

  • 相关阅读:
    回调函数和表驱动法编程
    学会看datasheet W25Q128为例
    STM32 Makefile的一次bug解决过程
    STM32 一种参数检查用法介绍
    STM32 中断和事件
    STM32 OV2640将数据缓存至SRAM
    STM32 .ld链接文件分析及一次bug解决过程
    浅谈嵌入式软件设计
    STM32 Makefile的设置和工程管理
    [转]Linux下的lds链接脚本详解
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/8080638.html
Copyright © 2011-2022 走看看