go log.Println(http.ListenAndServe(...)) blocks

207 views
Skip to first unread message

Christoph Berger

unread,
Feb 18, 2022, 11:35:52 AM2/18/22
to golang-nuts
Hi gophers,

I hope someone can help finding out why a particular goroutine call can block the main goroutine.

In the following code, all "go" calls spawn off a goroutine and return as expected, except for the last one that blocks the main goroutine.

Is this a bug, or am I missing something subtle or even obvious (obvious to all others only of course)?

package main

import (
        "log"
        "net/http"
)

func main() {
        // all of these work as expected
        go http.ListenAndServe("localhost:8080", nil)
        go log.Println("goroutine")
        go func() {
                log.Println(http.ListenAndServe("localhost:8081", nil))
        }()

        // The following line blocks the main goroutine.
        go log.Println(http.ListenAndServe("localhost:8082", nil))

        log.Println("after go log.Println(http.ListenAndServe())") // never prints
        select {} // remove this, and the code still never finishes
}

All three servers eventually run (try curl localhost:8080; curl localhost:8081; curl localhost:8082),

In the playground, the code even deadlocks.

Any idea?

Robert Engels

unread,
Feb 18, 2022, 11:48:59 AM2/18/22
to Christoph Berger, golang-nuts
Because the arguments are evaluated when the go keyword is encountered - and listen and serve is blocking on port 8082

On Feb 18, 2022, at 10:38 AM, Christoph Berger <christoph...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/fd72b5b3-f01e-44d5-a1a0-f784fe7b884fn%40googlegroups.com.

Sean Liao

unread,
Feb 18, 2022, 11:50:04 AM2/18/22
to golang-nuts
https://go.dev/ref/spec#Go_statements :

> The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete.

http.ListenAndServe is being evaluated, but it blocks.
Only the log.Println call would run in the newly started goroutine.

Christoph Berger

unread,
Feb 18, 2022, 12:23:06 PM2/18/22
to golang-nuts
(And I really should hit "reply to all", lol)

>
> > The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete.
(emphasis mine)

This explains it. I really should read the spec a bit more often. :)

Thanks Sean & Robert!
Reply all
Reply to author
Forward
0 new messages