这个空的 select-case-default 代码块有什么影响?

我试图理解一个池库代码,当实例化一个池结构时,调用一个名为 的函数startCleanerLocked(t Duration),在这个函数中,有一个空select...case...default...代码块,我不明白这个代码块的效果是什么。


Pool Interface是:


// Pool interface.

type Pool interface {

    Get(ctx context.Context) (io.Closer, error)

    Put(ctx context.Context, c io.Closer, forceClose bool) error

    Close() error

}

List Struct实施Pool Interface,


type List struct {

    // New is an application supplied function for creating and configuring a

    // item.

    //

    // The item returned from new must not be in a special state

    // (subscribed to pubsub channel, transaction started, ...).

    New func(ctx context.Context) (io.Closer, error)


    // mu protects fields defined below.

    mu     sync.Mutex

    cond   chan struct{}

    closed bool

    active int

    // clean stale items

    cleanerCh chan struct{}


    // Stack of item with most recently used at the front.

    idles list.List


    // Config pool configuration

    conf *Config

}

创建新池时,startCleanerLocked(t Duration)调用函数:


// NewList creates a new pool.

func NewList(c *Config) *List {

    // check Config

    if c == nil || c.Active < c.Idle {

        panic("config nil or Idle Must <= Active")

    }

    // new pool

    p := &List{conf: c}

    p.cond = make(chan struct{})

    p.startCleanerLocked(time.Duration(c.IdleTimeout))

    return p

}

在 中startCleanerLocked(t Duration),有一个select...case...default:


// startCleanerLocked

func (p *List) startCleanerLocked(d time.Duration) {

    if d <= 0 {

        // if set 0, staleCleaner() will return directly

        return

    }

    if d < time.Duration(p.conf.IdleTimeout) && p.cleanerCh != nil {

        select {

        case p.cleanerCh <- struct{}{}:

        default:

        }

    }

    // run only one, clean stale items.

    if p.cleanerCh == nil {

        p.cleanerCh = make(chan struct{}, 1)

        go p.staleCleaner()

    }

}

这个代码块的效果是什么:


select {

    case p.cleanerCh <- struct{}{}:

    default:

}

好像没什么可做的...


繁花如伊
浏览 92回答 1
1回答

一只甜甜圈

select {case p.cleanerCh <- struct{}{}:default:}这是一个非阻塞select语句。(因为有default:案例)如果在通道的另一端有一个接收器 goroutine p.cleanerCh,即当前有一个 goroutine 在接收操作中“等待” <-p.cleanerCh,则case p.cleanerCh <- struct{}{}立即执行它,这有效地解除了接收操作<-p.cleanerCh的阻塞,然后 goroutine 可以继续执行任何操作声明如下。如果没有接收者 goroutine,那么default:case 会立即执行,并且周围的startCleanerLocked函数可以继续执行语句后面的任何select语句。select {case <-ticker.C:case <-p.cleanerCh: // maxLifetime was changed or db was closed.}这是一个阻止select声明。(因为没有default:案例)该select语句阻塞for循环,直到两个通信案例之一准备好接收。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go