抢占式调度中信号处理函数如何判断当前是否在执行调度?

forxy · 2020-12-11 18:48:03 · 1922 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2020-12-11 18:48:03 的主题,其中的信息可能已经有所发展或是发生改变。

按道理,运行时在运行其他用户协程时,才应该执行抢占。运行时的调度代码不应该被抢占。那么,收到抢占信号处理时,如何判定当前是谁被中断执行? 在代码中,有如下代码: func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) { mp := gp.m

// Only user Gs can have safe-points. We check this first
// because it's extremely common that we'll catch mp in the
// scheduler processing this G preemption.
if mp.curg != gp {
    return false, 0
}

........ 但是对if mp.curg != gp 判断有疑问。 比如在调度代码中有下面这样的代码: 1 mp.curg = 用户协程g 2 切换到用户协程g 在执行1之后,未执行2之前收到了抢占信号,上面的判断语句 if mp.curg != gp 失效,不会返回false, 导致调度代码被抢占。

是否这样理解? 手机输入,若格式有问题,请谅解。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1922 次点击  
加入收藏 微博
2 回复  |  直到 2020-12-15 17:54:52
focusonline
focusonline · #1 · 4年之前

我觉得就算是抢占也有规则的, 1.不是说什么地方都可以被抢. 2.被抢占的断点是可以被栈保护起来的, 肯定有这个机制完成协程的现场保护

forxy
forxy · #2 · 4年之前

如果用c实现,可以有两种方法:

  1. 通过backtrace 来判断,这两者的调用栈是不一样的;
  2. 设置协程和线程堆栈时,通过mmap分配堆栈内存,让它们的地址隔开,在信号不理函数中,通过上下文的rsp寄存器来判断。
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传