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执行完毕自动退出。

参考资料

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

相关推荐
艾伦~耶格尔11 分钟前
【集合框架LinkedList底层添加元素机制】
java·开发语言·学习·面试
一只叫煤球的猫34 分钟前
🕰 一个案例带你彻底搞懂延迟双删
java·后端·面试
最初的↘那颗心35 分钟前
Flink Stream API 源码走读 - print()
java·大数据·hadoop·flink·实时计算
冒泡的肥皂1 小时前
MVCC初学demo(一
数据库·后端·mysql
JH30731 小时前
Maven的三种项目打包方式——pom,jar,war的区别
java·maven·jar
带刺的坐椅2 小时前
轻量级流程编排框架,Solon Flow v3.5.0 发布
java·solon·workflow·flow·solon-flow
David爱编程3 小时前
线程调度策略详解:时间片轮转 vs 优先级机制,面试常考!
java·后端
杨荧3 小时前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
阿冲Runner3 小时前
创建一个生产可用的线程池
java·后端
写bug写bug4 小时前
你真的会用枚举吗
java·后端·设计模式