channelx icon indicating copy to clipboard operation
channelx copied to clipboard

当队列满时,调出当前的携程,这个操作不可靠吧?

Open yudidi opened this issue 4 years ago • 3 comments

https://github.com/Ksloveyuan/channelx/blob/e2f4ef1a03814fc11c623795a65e7d404e39d616/aggregator.go#L72 请问这里的runtime.Gosched(),一定可能保证携程被调度走吗? 在哪些Go版本上有效呢?

yudidi avatar Oct 12 '21 11:10 yudidi

不确定你是指在什么时候不可靠,但无论如何,那里只是为了在下一个时间片尝试再次入队列,不成功就返回false吗。

Ksloveyuan avatar Oct 15 '21 14:10 Ksloveyuan

哦哦,我明白了,没有不可靠。 这个函数应该是一定能让当前携程让出CPU的。

func (agt *Aggregator) TryEnqueue(item interface{}) bool {
	select {
	case agt.eventQueue <- item:
		return true
	default:
		if agt.option.Logger != nil {
			agt.option.Logger.Warnf("Aggregator: Event queue is full and try reschedule")
		}

		runtime.Gosched() // 这个函数的作用是让当前goroutine让出CPU,好让其它的goroutine获得执行的机会。同时,当前的goroutine也会在未来的某个时间点继续运行。
                //  过一会儿再次调度到这个携程,继续往下执行。要么入队成功,要么返回入队失败。
		select {
		case agt.eventQueue <- item:
			return true // 入队成功
		default:
			if agt.option.Logger != nil {
				agt.option.Logger.Warnf("Aggregator: Event queue is still full and %+v is skipped.", item)
			}
			return false // 入队失败
		}
	}
}

yudidi avatar Nov 21 '21 10:11 yudidi

另外有个问题想请教下: runtime.Gosched()放在这里,是基于什么呢。性能 Or 减少某种冲突? 为什么不能像自旋锁一样,做几次自旋呢?

yudidi avatar Nov 21 '21 10:11 yudidi