Golang中的runtime.LockOSThread 和 runtime.UnlockOSThread

在runtime中有`runtime.LockOSThread 和 runtime.UnlockOSThread 两个函数,这两个函数有什么作用呢?我们看一下标准库中对它们的解释。

runtime.LockOSThread

复制代码
// LockOSThread wires the calling goroutine to its current operating system thread.
// The calling goroutine will always execute in that thread,
// and no other goroutine will execute in it,
// until the calling goroutine has made as many calls to
// UnlockOSThread as to LockOSThread.
// If the calling goroutine exits without unlocking the thread,
// the thread will be terminated.
//
// All init functions are run on the startup thread. Calling LockOSThread
// from an init function will cause the main function to be invoked on
// that thread.
//
// A goroutine should call LockOSThread before calling OS services or
// non-Go library functions that depend on per-thread state.

调用 LockOSThread 将 绑定 当前 goroutine 到当前 操作系统线程``,此 goroutine 将始终在此线程执行,其它 goroutine 则无法在此线程中得到执行,直到当前调用线程执行了 UnlockOSThread 为止(也就是说指定一个goroutine 独占 一个系统线程);

如果调用者goroutine 在未解锁线程(UnlockOSThread)之前直接退出,则当前线程将直接被终止(也就是说线程被直接销毁)。

我们知道在golang中创建的线程正常情况下是无法被销毁的,但通过这种hack用法则可以将其销毁,参考《极端情况下收缩 Go 的线程数》

所有 init函数 都运行在启动线程。如果在一个 init函数 中调用了 LockOSThread 则导致 main 函数被执行在当前线程。

goroutine应该在调用依赖于每个线程状态的 OS服务 或 非Go库函数 之前调用 LockOSThread。

总结

LockOSThread 是用来对 goroutine 与系统线程的关系进行绑定,起到独占系统线程的使用,带来的影响是会导致其它 goroutine 无法在当前系统线程中得到执行(goroutine的调度机制),除非调用 UnlockOSThread。

嵌套调用

另外还有一种情况是 嵌套调用 LockOSThread 和 UnlockOSThred 的情况。即当前 goroutine 里调用了LockOSThread, 同时又创建了一个新的goroutine的情况,官方对此进行了解释 https://tip.golang.org/doc/go1.10#runtime 。子协程是不会继承父协程的 LockOSThread 特性的。

runtime.UnlockOSThread

复制代码
// UnlockOSThread undoes an earlier call to LockOSThread.
// If this drops the number of active LockOSThread calls on the
// calling goroutine to zero, it unwires the calling goroutine from
// its fixed operating system thread.
// If there are no active LockOSThread calls, this is a no-op.
//
// Before calling UnlockOSThread, the caller must ensure that the OS
// thread is suitable for running other goroutines. If the caller made
// any permanent changes to the state of the thread that would affect
// other goroutines, it should not call this function and thus leave
// the goroutine locked to the OS thread until the goroutine (and
// hence the thread) exits.

UnlockOSThread 用于取消对 LockOSThread 的调用。

如果将调用 goroutine 的活跃 LockOSThread 调用数减为零,它从其固定的操作系统线程中取消调用 goroutine。即如果多次调用 LockOSThread,则必须将 UnlockOSThread 调用相同的次数才能解锁线程。

如果没有活跃的 LockOSThread 调用,则这是一个空操作。

在调用 UnlockOSThread 之前,调用者要确保当前线程适合运行其它goroutine。如果调用者对线程的状态做了任何永久性的更改,这将影响其他goroutine,那么它不应该调用此函数,从而使goroutine锁定到OS线程,直到goroutine(以及线程)退出,此时系统线程直接被销毁。

总结

UnlockOSThread 是对 LockOSThread 的反向操作,即解锁。用户可能在 LockOSThread 期间对操作系统线程进行了修改,所以有可能不再适合其它goroutine在当前系统线程运行,这种情况下就不再需要调用 UnlockOSThread,而是直接等待goroutine执行完毕自动退出。

参考资料

喜欢的朋友记得点赞、收藏、关注哦!!!

相关推荐
XIAEE2 分钟前
转生到儿童编程异世界:我用 Vue 和 Scratch 建了一座 DREAM 学院
java·spring
XIAEE9 分钟前
初次使用 Node + Koa + MongoDB 搭建服务器:从零到第一个 API
java·spring
m0_5873830014 分钟前
无人自助拼豆系统核心功能开发与部署落地全流程实战指南
java·经验分享·后端·struts·架构
毕业设计70319 分钟前
(免费领源码)基于node的学生公寓管理系统06412- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·mysql·node.js·maven·mybatis·express·b/s
雷一言说23 分钟前
Spring AI 2.0:RAG 文档分块大小策略选择
java·spring
XIAEE24 分钟前
Java 世界历险记:从一行 System.out.println 到整个 Spring 宇宙
java·spring
XIAEE26 分钟前
微前端狂想曲:我试图让三个不同门派的前端住进同一栋楼
java·spring
XIAEE26 分钟前
Linux 生存指南:从"终端恐惧症"到"命令行老司机"
java·spring
XIAEE27 分钟前
实战教程:手机端死活调不出摄像头?聊聊安全上下文(Secure Context)
java·spring
程序员清风27 分钟前
堆与优先队列:从 Top K 到任务调度
java·数据结构·算法