2 回答

TA貢獻1895條經驗 獲得超3個贊
您可以查看文件https://github.com/golang/go/blob/master/src/net/fd_unix.go(寫入函數(shù))。
基本上,這取決于套接字緩沖區(qū)是否有足夠的空間。
如果套接字緩沖區(qū)中有足夠的空間來容納您的寫操作的大小,數(shù)據(jù)將立即寫入套接字緩沖區(qū)。我想這對應于您的第二個答案。此外,內核實際上可能會發(fā)送數(shù)據(jù)包(或將其添加到 NIC 隊列),但它獨立于 Go 運行時。
如果套接字緩沖區(qū)中沒有足夠的空間來容納整個寫入操作,則只會立即將部分數(shù)據(jù)寫入套接字緩沖區(qū)。然后,調用將阻塞(通過運行時輪詢引擎),直到內核在套接字緩沖區(qū)中留出一些空間(通過發(fā)送一些數(shù)據(jù)包)。只要有一些空間可用,并且所有數(shù)據(jù)都已復制,呼叫就會解除阻塞。
您應該考慮在 net 包通過系統(tǒng)調用將整個緩沖區(qū)寫入套接字緩沖區(qū)時采用的時間戳。

TA貢獻1852條經驗 獲得超7個贊
在下面的文章介紹了netpoller是如何工作的:
每當 goroutine 嘗試讀取或寫入連接時,網絡代碼將執(zhí)行操作,直到收到此類錯誤,然后調用 netpoller,告訴它在準備再次執(zhí)行 I/O 時通知 goroutine。然后 goroutine 被調度到它正在運行的線程之外,另一個 goroutine 在它的位置運行。
當 netpoller 收到來自 OS 的通知,它可以對文件描述符執(zhí)行 I/O 時,它會查看其內部數(shù)據(jù)結構,查看是否有任何 goroutine 在該文件上被阻塞,如果有,則通知它們。然后 goroutine 可以重試導致它阻塞的 I/O 操作并成功執(zhí)行此操作?!?/p>
因此我們得出結論,只要底層系統(tǒng)調用完成對整個緩沖區(qū)的寫入,就可以重新調度 goroutine。在 Linux 的情況下,當消息被復制到內核空間發(fā)送緩沖區(qū)時似乎是蜜蜂:阻塞套接字:確切地說,“send()”何時返回?.?這又是我的第二個原始選項“當緩沖區(qū)被復制到運行時和操作系統(tǒng)的內核空間時”。
- 2 回答
- 0 關注
- 254 瀏覽
添加回答
舉報