码迷,mamicode.com
首页 > 其他好文 > 详细

golang _下划线占位符代替需要释放的资源的问题

时间:2017-12-21 16:04:10      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:下划线   baidu   main   进程   打开   场景   技术分享   turn   一个   

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中使用_下划线并不是靠谱的。

golang _下划线占位符代替需要释放的资源的问题

标签:下划线   baidu   main   进程   打开   场景   技术分享   turn   一个   

原文地址:http://www.cnblogs.com/xiaxiaosheng/p/8080638.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!