在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執行完畢自動退出。
參考資料
- https://tip.golang.org/doc/go1.10#runtime
- https://stackoverflow.com/questions/25361831/benefits-of-runtime-lockosthread-in-golang
- http://xiaorui.cc/archives/5320
- 極端情況下收縮 Go 的線程數
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務

喜歡的朋友記得點贊、收藏、關注哦!!!