在我的機器上有 4 個邏輯處理器。所以有四個上下文P1, P2, P3&P4使用 OS 線程M1, M2, M3&M4$ lscpuArchitecture: x86_64CPU op-mode(s): 32-bit, 64-bitByte Order: Little EndianCPU(s): 4On-line CPU(s) list: 0-3Thread(s) per core: 2Core(s) per socket: 2Socket(s): 1在下面的代碼中:package mainimport ( "fmt" "io/ioutil" "net/http")func getPage(url string) (int, error) { resp, err := http.Get(url) if err != nil { return 0, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return 0, err } return len(body), nil}func worker(urlChan chan string, sizeChan chan<- string, i int) { for { url := <-urlChan length, err := getPage(url) if err == nil { sizeChan <- fmt.Sprintf("%s has length %d (%d)", url, length, i) } else { sizeChan <- fmt.Sprintf("%s has error %s (%d)", url, err, i) } }}func main() { urls := []string{"http://www.google.com/", "http://www.yahoo.com", "http://www.bing.com", "http://bbc.co.uk", "http://www.ndtv.com", "https://www.cnn.com/"} urlChan := make(chan string) sizeChan := make(chan string) for i := 0; i < len(urls); i++ { go worker(urlChan, sizeChan, i) } for _, url := range urls { urlChan <- url } for i := 0; i < len(urls); i++ { fmt.Printf("%s\n", <-sizeChan) }}有六個執行例程http.Get()1)OS thread() 是否被io() 上M1的 go-routine() 阻塞?上下文G1http.Get()P1或者G1Go 調度程序是否會從 OS 線程(M1)搶占 go-routine( ) http.Get()?并分配G2給M1... 如果是,則在搶占 時G1,G1Goruntime如何G1在 IO() 完成后恢復http.Get?2)檢索用于每個 go-routine(G) 的上下文編號 (P) 的 api 是什么?用于調試目的..3) 我們使用 C pthreads 庫為上述讀寫器問題使用計數信號量維護關鍵部分。為什么我們不使用 go-routines 和通道來使用關鍵部分?
1 回答

有只小跳蛙
TA貢獻1824條經驗 獲得超8個贊
不,它不會阻塞。我粗略的(并且沒有來源,我是通過 osmosis 得到的)理解是,每當一個 goroutine 想要執行一個具有等效非阻塞版本的“阻塞”I/O 時,
改為執行非阻塞版本。
將它自己的 ID 記錄在一個由它“阻塞”的句柄鍵入的表中。
將完成的責任轉移到一個專用線程,該線程位于
select
循環中(或poll
任何可用的等效線程)等待此類操作解除阻塞,并且掛起自身,釋放其操作系統線程(M)以運行另一個 goroutine。
當 I/O 操作解除阻塞時,選擇循環在表中查找哪個 goroutine 對結果感興趣,并安排它運行。這樣,等待 I/O 的 goroutine 就不會占用一個 OS 線程。
在無法以非阻塞方式完成的 I/O 或任何其他阻塞系統調用的情況下,goroutine 通過將其線程標記為阻塞的運行時函數執行系統調用,并且運行時將為 goroutines 創建一個新的 OS 線程以被安排在。這保持了讓 GOMAXPROCS 運行(未阻塞)goroutines 的能力。對于大多數程序來說,這不會導致太多的線程膨脹,因為用于處理文件、套接字等的最常見的系統調用已經變得異步友好。(感謝@JimB 提醒我這一點,以及有用的鏈接答案的作者。)
- 1 回答
- 0 關注
- 143 瀏覽
添加回答
舉報
0/150
提交
取消