Golang中的runtime.LockOSThread 和 runtime.UnlockOSThread

在runtime中有`runtime.LockOSThreadruntime.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

嵌套调用

另外还有一种情况是 嵌套调用 LockOSThreadUnlockOSThred 的情况。即当前 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执行完毕自动退出。

参考资料

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

相关推荐
C1829818257510 分钟前
HttpURLConnection 与其他客户端关系
java
weixin_4481199424 分钟前
Datawhale Hello-Agents入门篇202512第1次作业
数据库·sql·mysql
皮皮林55125 分钟前
有了开源的 MySQL,为什么还要选择 PostgreSQL?
mysql
通往曙光的路上26 分钟前
发邮件1、创建邮箱
java
五阿哥永琪42 分钟前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python
麦麦鸡腿堡1 小时前
Java_类的加载
java·开发语言
JIngJaneIL1 小时前
基于java + vue校园快递物流管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js
超级大只老咪1 小时前
数组的正向存储VS反向存储(Java)
java·开发语言·python
毕设源码-赖学姐1 小时前
【开题答辩全过程】以 基于JSP的物流信息网的设计与实现为例,包含答辩的问题和答案
java·开发语言