[英]Does OS thread get blocked on io performed by go-routine?
在我的機器上有 4 個邏輯處理器。 所以有四個上下文P1
, P2
, P3
和P4
與操作系統線程M1
, M2
, M3
和M4
一起使用
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
在下面的代碼中:
package main
import (
"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()
的 go-routines
1)
OS線程( M1
)是否被io( http.Get()
)上的go-routine( G1
)阻塞? 在上下文P1
或者
Go 調度程序是否在http.Get()
) 上從 OS 線程 ( M1
) 搶占 go-routine ( G1
) ? 並將G2
分配給M1
...如果是,在搶占G1
時,Goruntime 如何管理G1
以在完成 IO 后恢復G1
( http.Get
)?
2)
檢索用於每個 go-routine (G) 的上下文編號 (P) 的 api 是什么? 用於調試目的..
3)我們使用計數信號量維護臨界區,使用 C pthreads 庫解決上述讀寫器問題。 為什么我們不使用 go-routines 和通道來使用關鍵部分?
不,它不會阻塞。 我粗略的(並且沒有來源,我是通過 osmosis 得到的)理解是,每當一個 goroutine 想要執行一個具有等效非阻塞版本的“阻塞”I/O 時,
select
循環(或poll
或任何可用的等效項)中,等待此類操作解除阻塞,並且當 I/O 操作解除阻塞時,選擇循環在表中查找哪個 goroutine 對結果感興趣,並安排它運行。 這樣,等待 I/O 的 goroutine 就不會占用一個 OS 線程。
在無法以非阻塞方式完成的 I/O 或任何其他阻塞系統調用的情況下,goroutine 通過運行時 function 執行系統調用,將其線程標記為阻塞,運行時將為 goroutine 創建一個新的 OS 線程被安排在。 這保持了讓 GOMAXPROCS 運行(未阻塞)goroutines 的能力。 對於大多數程序來說,這不會導致太多的線程膨脹,因為用於處理文件的最常見系統調用 sockets 等已變得異步友好。 (感謝@JimB 提醒我這一點,以及有用的鏈接答案的作者。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.