Ety*_*Ety 0 concurrency multithreading go httpserver
我正在使用golang创建一个简单的http服务器.我有两个问题,一个是更理论的,另一个是关于真实的程序.
我创建一个服务器并使用s.ListenAndServe()来处理请求.尽管我理解同时提供的请求.我使用一个简单的处理程序来检查它:
func ServeHTTP(rw http.ResponseWriter, request *http.Request) {
fmt.Println("1")
time.Sleep(1 * time.Second) //Phase 2 delete this line
fmt.Fprintln(rw, "Hello, world.")
fmt.Println("2")
}
Run Code Online (Sandbox Code Playgroud)
我看到,如果我发送了几个请求,我会看到所有"1"出现,并且只有在第二个出现"2"之后.但是如果我删除了Sleep行,我会看到该程序在完成前一个请求之前从未启动过请求(输出为1 2 1 2 1 2 ...).所以我不明白,如果他们是并发或不是真的.如果他们是我希望看到一些混乱的印刷品......
在真正的处理程序中,我将请求发送到另一个服务器并将答案返回给用户(对请求和答案进行了一些更改,但在想法中它是一种代理).所有这些当然需要时间和从可以看到的内容(通过向处理程序添加一些打印),请求被逐个处理,它们之间没有并发(我的打印显示请求开始,执行所有步骤,结束,然后才看到一个新的开始......).我该怎么做才能让它们真正并发?
将处理程序函数设置为goroutine会产生错误,请求的主体已经关闭.此外,如果已经并发添加更多goroutines将使事情变得更糟.
谢谢!
你的例子很难说出发生了什么.
以下示例将清楚地说明请求是并行运行的.
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if len(r.FormValue("case-two")) > 0 {
fmt.Println("case two")
} else {
fmt.Println("case one start")
time.Sleep(time.Second * 5)
fmt.Println("case one end")
}
})
if err := http.ListenAndServe(":8000", nil); err != nil {
log.Fatal(err)
}
}
Run Code Online (Sandbox Code Playgroud)
向http:// localhost:8000发出一个请求
在5秒内向http:// localhost:8000发出另一个请求?case-two = true
控制台输出将是
case one start
case two
case one end
Run Code Online (Sandbox Code Playgroud)