Golang的一些坑

栏目: Go · 发布时间: 7年前

内容简介:此函数退出时,会有两个goroutine被阻塞在channel上, 然而gc不会回收. 因此, 如果大量出现这种情况, 将会导致goroutine leak.操作channel都要加锁。所以略慢。因为结构体就是这么定义的 :)
  • 传给 signal.Notify 的channel必须是一个buffered channel, 否则收不到信号

  • channel默认是unbuffered channel, 因此在没有消费者之前, 放入channel的动作都会被阻塞, 例如:

func main() {
    c := make(chan int)

    for i := 0; i < 3; i++ {
        go func() {
            c <- 1
        }()
    }

    fmt.Println(<-c)
}

此函数退出时,会有两个goroutine被阻塞在channel上, 然而gc不会回收. 因此, 如果大量出现这种情况, 将会导致goroutine leak.

type hchan struct {
    qcount   uint           // total data in the queue。总数
    dataqsiz uint           // size of the circular queue。make(chan, 3)中的3.大小。也是下面的buf的大小
    buf      unsafe.Pointer // points to an array of dataqsiz elements
    elemsize uint16         // 每个元素有多大
    closed   uint32
    elemtype *_type // element type 元素是啥类型
    sendx    uint   // send index 发送的序号
    recvx    uint   // receive index 接收的序号
    recvq    waitq  // list of recv waiters 等待接收的G。sudog链表。
    sendq    waitq  // list of send waiters 等待发送的G。sudog链表。

    // lock protects all fields in hchan, as well as several
    // fields in sudogs blocked on this channel.
    //
    // Do not change another G's status while holding this lock
    // (in particular, do not ready a G), as this can deadlock
    // with stack shrinking.
    // 加锁加锁。不用atomic的原因大概是chan的缓冲数量,等待发送数量和接受者数量都不定的吧。
    // 加锁简单好用,代价就是性能略差
    lock mutex
}

操作channel都要加锁。所以略慢。

  • slice是共享底层数据的,为何?
// slice的结构体,一个指针,一个长度,一个容量
type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}

因为结构体就是这么定义的 :)

从fasthttp里学到一招避免 string[]byte 开销的方式:

package main

import (
    "bufio"
    "fmt"
    "os"
    "reflect"
    "unsafe"
)

// s2b converts string to a byte slice without memory allocation.
//
// Note it may break if string and/or slice header will change
// in the future go versions.
func s2b(s string) []byte {
    sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
    bh := reflect.SliceHeader{
        Data: sh.Data,
        Len:  sh.Len,
        Cap:  sh.Len,
    }
    return *(*[]byte)(unsafe.Pointer(&bh))
}

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    hello, _ := reader.ReadString('\n')
    fmt.Println(hello)
    helloBytes := s2b(hello)
    helloBytes[1] = 'w'
    fmt.Println(hello)
}

执行一下:

$ ./tests 
Enter text: hello
hello
hwllo

不过要注意不能直接写 hello := "hello" 这样来改,因为如果显式写明字符串的话, 编译器会把它放在栈里,而不是像上面的代码一样在堆里搞。


以上所述就是小编给大家介绍的《Golang的一些坑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人人都在晒,凭什么你出彩

人人都在晒,凭什么你出彩

【美】奥斯丁•克莱恩 / 张舜芬、徐立妍 / 北京联合出版公司 / 2015-4 / 38.00

1. 《纽约时报》、亚马逊畅销书排名第1位、好评如潮的创意营销书。《出版人周刊》称其在社交网络时代“在安全范围内提供了实用的自我营销策略”。 2. TED演讲者创意分享:晒对了,全世界都为你点赞:别人在朋友圈、微博晒自拍、晒孩子、晒吃喝,你来晒创意、晒灵感、晒工作、晒收获,发出自己的声音,找到伙伴,机会也会主动找上门! 3. 10堂创意课+手绘涂鸦,所有人都能轻松读完、迅速学会的创意小......一起来看看 《人人都在晒,凭什么你出彩》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具