久趣下载站

当前位置: 首页 » 游戏攻略 » goroutine系统调用时间过长的抢占机制

goroutine系统调用时间过长的抢占机制

原创文章,欢迎转载,转载请注明出处,谢谢。


第八讲介绍了当goroutine运行时间过长会被抢占的情况。本文将继续探讨goroutine执行系统调用时间过长的抢占机制。

看下面的示例:

func longSyscall() {
	timeout := syscall.NsecToTimeval(int64(5 * time.Second))
	fds := make([]syscall.FdSet, 1)

	if _, err := syscall.Select(0, &fds[0], nil, nil, &timeout); err != nil {
		fmt.Println("Error:", err)
	}

	fmt.Println("Select returned after timeout")
}

func main() {
	threads := runtime.GOMAXPROCS(0)
	for i := 0; i < threads; i++ {
		go longSyscall()
	}

	time.Sleep(8 * time.Second)
}

longSyscall goroutine执行一个5秒的系统调用。在系统调用过程中,sysmon会监控longSyscall,发现执行系统调用时间过长,会对其进行抢占。

sysmon线程会监控并抢占系统调用时间过长的goroutine。它的抢占逻辑如下:

func sysmon() {
    ...
    idle := 0 // 连续多少个周期没有唤醒其他goroutine
    delay := uint32(0)
    ...

    for {
		if idle == 0 { // 从20微秒的休眠开始…
			delay = 20
		} else if idle > 50 { // 1毫秒后开始加倍休眠…
			delay *= 2
		}
		if delay > 10*1000 { // 最多10毫秒
			delay = 10 * 1000
		}
		usleep(delay)

        ...
        // 重新获取处于系统调用的P
		// 并抢占运行时间过长的G
		if retake(now) != 0 {
			idle = 0
		} else {
			idle++
		}
        ...
    }
}

类似于运行时间过长的goroutine,调用retake进行抢占。retake函数用于抢占处于_Prunning或_Psyscall状态的goroutine。对于系统调用时间过长的goroutine,也会进行抢占。

进入handoffp:

// 从系统调用或锁定的M中释放P
// 始终在没有P的情况下运行,因此不允许写屏障。
//
//go:nowritebarrierrec
func handoffp(pp *p) {
    // 如果P的本地队列有工作,立即开始工作
    // 如果P的本地队列有工作或全局队列有工作,则将P与其他线程绑定,以释放P
	if !runqempty(pp) || sched.runqsize != 0 {
		startm(pp, false, false)
		return
	}

    ...
    // 没有本地工作,检查是否有自旋/空闲的M
	// 如果有,则不需要帮助
	if sched.nmspinning.Load()+sched.npidle.Load() == 0 && sched.nmspinning.CompareAndSwap(0, 1) { // TODO: fast atomic
		sched.needspinning.Store(0)
		startm(pp, true, false)
		return
	}

    ...
    // 如果全局队列有工作,则释放P
    if sched.runqsize != 0 {
		unlock(&sched.lock)
		startm(pp, false, false)
		return
	}

    ...
    // 如果没有工作,则将P放入全局空闲队列
    pidleput(pp, 0)
	unlock(&sched.lock)
}

可以看到,抢占系统调用时间过长的goroutine,抢占的意思是释放系统调用线程所绑定的P,而不是阻止线程执行系统调用。抢占的目的是合理利用P资源。抢占完成后,增加抢占次数n,retake函数返回。

本文介绍了系统调用时间过长引起的抢占机制。下一篇文章将继续介绍异步抢占。


猜你喜欢
本类排行