Goroutine concept: direct call vs call using function literal

Issue

What are the basic differences between below two codes? Somehow, in the second example demo_process2() is never called but it works fine in the first example.

    1.
go func() {
    Must(demo_process1())
}()

demo_process2()
    2.
go Must(demo_process1())
demo_process2()

where Must():

func Must(err error) {
    if err != nil {
        panic(err)
    }
}

Solution

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. Instead, the function begins executing independently in a new goroutine.

In your first example you launch an anonymous function (a function literal) with no parameters as a new goroutine. Must() and demo_process1() are called inside that, concurrently with demo_process2() (which is executed in the “original” goroutine).

In your second example however:

go Must(demo_process1())
demo_process2()

The function launched as a goroutine is Must(), and its parameters are evaluated in the calling goroutine. Parameter of Must() is the return value of demo_process1(), which means demo_process1() is called and waited for first before a new goroutine is launched. Only when it returns may the new goroutine be started and demo_process2() be called (on the “original” goroutine).

All in all, in the second example demo_process1() and demo_process2() are not running concurrently but sequentially, in the same goroutine. Only the Must() is executed on a new goroutine (concurrently with demo_process2()).

Answered By – icza

Answer Checked By – Gilberto Lyons (GoLangFix Admin)

Leave a Reply

Your email address will not be published.