天天看点

Golang结构体知识

对golang稍微熟悉的兄弟姐妹们就不用看了!

Golang结构体知识
在看Docker源码时,碰到了这个语句:

container.Lock()           

看到上面直接对struct Container进行上锁时,我翻了一下这个结构体,发现没有定义任何锁啊,怎么上锁的咧。于是我就翻了一下这个结构

体的一些子属性,发现了State的定义

// container/container.go
type Container struct {
    StreamConfig *stream.Config
    // embed for Container to support states directly.
    *State          `json:"State"`          // Needed for Engine API version <= 1.11
    Root            string                  `json:"-"` // Path to the "home" of the container, including metadata.
    BaseFS          containerfs.ContainerFS `json:"-"` // interface containing graphdriver mount
    RWLayer         layer.RWLayer           `json:"-"`
    ....   
}
// container/state.go
type State struct {
    sync.Mutex
    // Note that `Running` and `Paused` are not mutually exclusive:
    // When pausing a container (on Linux), the cgroups freezer is used to suspend
    // all processes in the container. Freezing the process requires the process to
    // be running. As a result, paused containers are both `Running` _and_ `Paused`.
    Running           bool
    Paused            bool
    Restarting        bool
    OOMKilled         bool
    RemovalInProgress bool // Not need for this to be persistent on disk.
    Dead              bool
    Pid               int
    ExitCodeValue     int    `json:"ExitCode"`
    ErrorMsg          string `json:"Error"` // contains last known error during container start, stop, or remove
    StartedAt         time.Time
    FinishedAt        time.Time
    Health            *Health
    waitStop   chan struct{}
    waitRemove chan struct{}
}           

当时看到这我就纳闷了(go没学过,没写过,完全新手),咋就直接访问到State里面的内容了。

看到没,Container结构体里面定义了*State之后,就可以直接访问State里面的成员,这有点类似继承啥玩意的。接下来我们就做个测试,可以瞅瞅。

package main
import (
    "fmt"
    "sync"
)
type State struct {
    sync.Mutex
    Running bool
    Paused bool
}
type Container struct {
    *State
    ID string
}
func NewState() *State {
    return &State{
        Running: false,
        Paused: false,
    }
}
func (c *Container) getInfo() error {
    c.Lock()
    defer c.Unlock()  // defer 可以另写一篇文章说一下
    fmt.Println("container is locked")
    return nil
}
func main() {
    c := Container{State: NewState()}
    c.getInfo()
    c.Lock()
    fmt.Println("second lock")
    c.Unlock()
}           

运行上面的程序,就可以看到Container可以直接访问到State里面的锁。

Golang结构体知识

参考:

兔子哥哥

继续阅读