亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Go 中,變量何時會變得不可訪問?

在 Go 中,變量何時會變得不可訪問?

Go
米琪卡哇伊 2022-01-17 10:33:50
Go 1.7 beta 1 于今天早上發布,這里是Go 1.7 的發布說明草稿。一個新功能KeepAlive被添加到包runtime中。的文檔runtime.KeepAlive給出了一個例子:type File struct { d int }d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)// ... do something if err != nil ...p := &FILEpap3e3vruntime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })var buf [10]byten, err := syscall.Read(p.d, buf[:])// Ensure p is not finalized until Read returns.runtime.KeepAlive(p)// No more uses of p after this point.的文檔runtime.SetFinalizer還對以下內容進行了解釋runtime.KeepAlive:例如,如果 p 指向一個包含文件描述符 d 的結構,并且 p 具有關閉該文件描述符的終結器,并且如果函數中最后一次使用 p 是對 syscall.Write(pd, buf, size ),那么一旦程序進入 syscall.Write,p 就可能無法訪問。終結器可能在那個時候運行,關閉 pd,導致 syscall.Write 失敗,因為它正在寫入一個關閉的文件描述符(或者更糟糕的是,寫入由不同的 goroutine 打開的完全不同的文件描述符)。為避免此問題,請在調用 syscall.Write 之后調用 runtime.KeepAlive(p)。令我困惑的是,變量p還沒有離開它的生命范圍,為什么它會無法訪問?這是否意味著只要在以下代碼中沒有使用變量,無論它是否在其生命范圍內,它都將無法訪問?
查看完整描述

1 回答

?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

當運行時檢測到Go代碼無法到達再次引用該變量的點時,該變量將變得不可訪問。

在您發布的示例中, asyscall.Open()用于打開文件。返回的文件描述符(只是一個int值)被“包裝”在struct. 然后一個終結器附加到這個結構值上,關閉文件描述符?,F在,當這個結構值變得不可訪問時,它的終結器可能隨時運行,并且文件描述符的關閉/失效/重用可能會導致Read()系統調用執行時出現意外行為或錯誤。

pGo代碼中這個結構值的最后一次使用是什么時候syscall.Read()被調用(并且文件描述符p.d被傳遞給它)。系統調用的實現將在啟動后使用該文件描述符syscall.Read(),它可能會一直這樣做直到syscall.Read()返回。但是文件描述符的這種使用是“獨立”于 Go 代碼的。

所以p在執行系統調用期間不使用結構值,系統調用會阻塞 Go 代碼,直到它返回。這意味著允許 Go 運行時p在執行期間Read()Read()返回之前)或什至在其實際執行開始之前標記為不可訪問(因為p僅用于為 call 提供參數Read()。

因此調用runtime.KeepAlive(): 因為這個調用在之后并且syscall.Read()引用了變量p,所以 Go 運行時不允許在返回p之前標記 unreachable Read(),因為這是在Read()調用之后。

請注意,您可以使用其他構造來“保持p活力”,例如_ = p或返回它。runtime.KeepAlive()在后臺沒有做任何神奇的事情,它的實現是:

func KeepAlive(interface{}) {}

runtime.KeepAlive() 確實提供了更好的選擇,因為:

  • 它清楚地記錄了我們想要保持p活動狀態(以防止運行Finalizers)。

  • 使用其他結構,例如_ = p可能會被未來的編譯器“優化”出來,但不會被runtime.KeepAlive()調用。


查看完整回答
反對 回復 2022-01-17
  • 1 回答
  • 0 關注
  • 188 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號