Golang支持LockOSThread()
使当前的goroutine与当前的OS线程完全绑定,它也可以UnlockOSThread()
。
是否有任何用例受益于此功能?
答案 0 :(得分:19)
使用Go线程模型,对C代码,汇编程序代码或阻塞系统调用的调用发生在与调用Go代码相同的线程中,该代码由Go运行时调度程序管理。
当Go必须与某些外部库(例如C库)接口时,os.LockOSThread()
机制非常有用。它保证在同一个线程中对该库进行多次连续调用。
在以下几种情况下这很有趣:
许多graphic libraries(OS X Cocoa,OpenGL,SDL,...)要求在特定线程(或某些情况下的主线程)上完成所有调用。
一些外国图书馆基于thread local storage(TLS)设施。它们将一些上下文存储在附加到线程的数据结构中。或者API的某些功能提供其内存生命周期附加到线程的结果。这个概念用于Windows和类Unix系统。典型示例是C库中常用于存储错误代码的errno全局变量。在支持多线程的系统上,errno通常被定义为线程局部变量。
更一般地说,一些外国图书馆可能会使用线程标识符来索引/管理内部资源。
答案 1 :(得分:4)
runtime.LockOsThread它通常用于调用需要在主线程中运行的C代码,如图形库中那样。
关于LockOsThread的Wiki page以及如何使用它的示例。
Google将discussion组织在SDL中使用LockOsThread。
答案 2 :(得分:0)
作为mentioned here,runtime.LockOSThread
做的是阻止任何其他goroutine在同一个线程上运行。
但请注意Go 1.10 (Q1 2018)会稍微改变其用法:
因为
LockOSThread
和UnlockOSThread
的一个常见用法是允许Go代码可靠地修改线程本地状态(例如,Linux或Plan 9名称空间),所以运行时现在将锁定的线程视为不适合重用或创建新线程。
LockOSThread
和UnlockOSThread
的嵌套调用的行为已发生变化。这些函数控制是否将goroutine锁定到特定的操作系统线程,以便goroutine仅在该线程上运行,并且线程仅运行该goroutine。以前,连续多次调用
LockOSThread
相当于调用一次,而单个UnlockOSThread
始终解锁该线程。现在,调用嵌套:如果多次调用
LockOSThread
,则必须调用UnlockOSThread
相同的次数才能解锁线程。