第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

Goroutines 破壞了程序

Goroutines 破壞了程序

Go
慕慕森 2021-06-08 17:00:01
問題是:有一個網(wǎng)絡服務器。我認為在頁面加載中使用 goroutines 是有益的,所以我繼續(xù)這樣做:將 loadPage 函數(shù)稱為 goroutine。但是,在執(zhí)行此操作時,服務器只會停止工作而不會出錯。它會打印一張空白的白頁。問題必須出在函數(shù)本身 - 不知何故與 goroutine 存在沖突。這些是相關(guān)的功能:func loadPage(w http.ResponseWriter, path string) {   s := GetFileContent(path)   w.Header().Add("Content-Type", getHeader(path))   w.Header().Add("Content-Length", GetContentLength(path))   fmt.Fprint(w, s)}func GetFileContent(path string) string {   cont, err := ioutil.ReadFile(path)   e(err)   aob := len(cont)   s := string(cont[:aob])   return s}func GetFileContent(path string) string {   cont, err := ioutil.ReadFile(path)   e(err)   aob := len(cont)   s := string(cont[:aob])   return s}func getHeader(path string) string {   images := []string{".jpg", ".jpeg", ".gif", ".png"}   readable := []string{".htm", ".html", ".php", ".asp", ".js", ".css"}   if ArrayContainsSuffix(images, path) {      return "image/jpeg"   }   if ArrayContainsSuffix(readable, path) {      return "text/html"   }   return "file/downloadable"}func ArrayContainsSuffix(arr []string, c string) bool {   length := len(arr)   for i := 0; i < length; i++ {      s := arr[i]      if strings.HasSuffix(c, s) {         return true      }   }return false}
查看完整描述

2 回答

?
呼如林

TA貢獻1798條經(jīng)驗 獲得超3個贊

之所以出現(xiàn)這種情況的原因是因為你的HandlerFunc其稱之為“l(fā)oadPage”與請求同步調(diào)用。當您在 go 例程中調(diào)用它時,處理程序?qū)嶋H上是立即返回,從而立即發(fā)送響應。這就是為什么你會得到一個空白頁。


您可以在server.go 中看到這一點(第 1096 行):


serverHandler{c.server}.ServeHTTP(w, w.req)

if c.hijacked() {

    return

}

w.finishRequest()

該ServeHTTP函數(shù)調(diào)用您的處理程序,并在返回后立即調(diào)用“finishRequest”。因此,只要您的 Handler 函數(shù)想要滿足請求,它就必須阻塞。


使用 go 例程實際上不會使您的頁面更快。正如 Philip 建議的那樣,將單個 go 例程與通道同步,在這種情況下也無濟于事,因為這與根本沒有 go 例程相同。


您的問題的根源實際上是ioutil.ReadFile,它在發(fā)送之前將整個文件緩沖到內(nèi)存中。


如果要流式傳輸文件,則需要使用os.Open. 您可以使用io.Copy將文件內(nèi)容流式傳輸?shù)綖g覽器,瀏覽器將使用分塊編碼。


這看起來像這樣:


f, err := os.Open(path)

if err != nil {

    http.Error(w, "Not Found", http.StatusNotFound)

    return

}

n, err := io.Copy(w, f)

if n == 0 && err != nil {

    http.Error(w, "Error", http.StatusInternalServerError)

    return

}

如果由于某種原因您需要在多個 go 例程中工作,請查看sync.WaitGroup. 渠道也可以工作。


如果您只想提供一個文件,則還有其他為此進行了優(yōu)化的選項,例如FileServer或ServeFile。


查看完整回答
反對 回復 2021-06-21
  • 2 回答
  • 0 關(guān)注
  • 194 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號