2017-11-20 14 views
-2

darwin/amd64의 Go 1.9.2로 작성된 goroutine은 런타임 오류가 발생합니다. 잘못된 메모리 주소 또는 nil 포인터 참조 취소입니다. 루틴 종료 순서와 관련된 일종의 경쟁 조건으로 생각합니다. 그러나 확실하지 않습니다.HTTP.Server 종료로 인해 런타임 오류가 발생합니다.

주 응용 프로그램에서 수행하는 몇 가지 작업이 있으므로 웹 서버를 goroutine으로 시작하여 부모 프로세스의 종료 신호를 수신 한 다음 반환하기 전에 모든 내용을 완전히 종료하려고 시도합니다. ,

if err := srv.Shutdown(nil); err != nil { 

가 트리거되고 일관 아니지만 다음 공황 상태

// WebServer defines the handler endpoints and launches the web server listener 
func WebServer(wg *sync.WaitGroup) { 

    // Make sure the exit is noted 
    defer wg.Done() 

    // Endpoint, handler function 
    http.HandleFunc("/version", WebShowVersion) 

    // Go forth and serve 
    // Define the server struct 
    srv := &http.Server{Addr: ":8080"} 

    // Now go serve 
    chnToLogger <- "Launching web server on port 8080" 
    go func() { 
     err := srv.ListenAndServe() 
     if err != nil && 
      err.Error() != "http: Server closed" { 

      // There...was an error 
      chnToLoggerError <- "Error launching web server: " + err.Error() 
     } 
    }() 

    // Listen for a shutdown 
    for { 
     select { 
     case <-chnQuitNow: 

      // Shut down the process 
      chnToLogger <- "Shutting down web server process" 
      if err := srv.Shutdown(nil); err != nil { 

       // There was a problem shutting down gracefully 
       chnToLoggerError <- "Error shutting down web server: " + err.Error() 
       return 
      } 

      // Done 
      chnToLogger <- "Web server has shut down now" 
      return 

     default: 
      continue 
     } 
    } 

    // Done 
    return 
} 

: webhandling.go에

panic: runtime error: invalid memory address or nil pointer dereference 
[signal SIGSEGV: segmentation violation code=0x1 addr=0x28 pc=0x11f7e61] 

goroutine 10 [running]: 
net/http.(*Server).Shutdown(0xc420158000, 0x0, 0x0, 0x0, 0x0) 
    /usr/local/go/src/net/http/server.go:2506 +0x1b1 
main.WebServer(0xc4200164a0) 
    /Users/me/go/src/testproj/webhandling.go:45 +0x146 
created by main.main 
    /Users/me/go/src/testproj/main.go:94 +0x3d6 

라인 (45)은

여기서 함수의 프로그램을 시작하고 로컬 호스트를 끌어 오기 위해 웹 클라이언트를 사용하는 경우에만 발생하는 것 같습니다 : 8080/version a fe w times, srv.Shutdown (nil)이 참조가 있지만 이미 종료 된 연결을 닫으려고하는지 궁금하게 생각하십니까?

1) goroutine에서 돌아 오기 전에 서버가 웹 서버 프로세스를 안전하고 완벽하게 종료 할 수 있습니까?

2) 일관성없는 런타임 오류가 발생하게하는 원인은 무엇입니까?

+1

종료가 'nil'이 될 수있는 문맥입니까? – mkopriva

+0

.. 'Shutdown'이 (가) 소스에 대해 보호하고 있다고 소스의 어느 곳에서도 볼 수 없습니다 (https://github.com/golang/go/blob/master/src/net/http/server.go#L2514-L2538). 없음. – mkopriva

+0

@mkopriva - 필자는이 질문에서 받아 들여지는 "구체적인 예"에 함수를 기반으로 사용했습니다.이 예제에서는 무를 사용했습니다. https://stackoverflow.com/questions/39320025/how-to-stop-http-listenandserve 정확하지 않거나 잘못되었습니다. 그냥 사용하는 이유는 무엇입니까?) –

답변