Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

channel with net.http, no deadlock, why #33004

Closed
georgehao opened this issue Jul 9, 2019 · 13 comments

Comments

@georgehao
Copy link

commented Jul 9, 2019

What version of Go are you using (go version)?

go version go1.12.2 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/haohongfan/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/xx/go"
GOPROXY="https://goproxy.io"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.12.2/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.12.2/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/haohongfan/goproject/test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/9q/mcmf4t9x6qgf9bc4x83nvl5m0000gn/T/go-build979680138=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

if a channel without buffer, send data to channel but not receive, it must be deadlock, eg

func main() {
	waitQueue := make(chan int)
	for {
		waitQueue <- 1
	}
}

output: fatal error: all goroutines are asleep - deadlock!

But when this build with net/http, the deadlock is missing, only block the program, WHY

eg

func main() {
        fmt.Println("xxx")
	waitQueue := make(chan int)
	waitQueue <- 1
	return

	server, err := net.Listen("tcp", "127.0.0.1:9001")
	if err != nil {
		fmt.Println(err)
	}

	for {
		connection, err := server.Accept()
		if err != nil {
			panic("server")
		}
		fmt.Printf("Received connection from %s.\n", connection.RemoteAddr())
		//go func(c net.Conn) {
		//connection.Close()
		//}(connection)
	}
}

output:

xxx

What did you expect to see?

As I see the official document, This must get deadlock, but result not.

What did you see instead?

deadlock

@bcmills bcmills added the Question label Jul 9, 2019

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

The built-in deadlock detector only flags states in which the program is guaranteed not to make further progress — it does not flag conditions in which some goroutine is guaranteed not to make progress (which we call “goroutine leaks”).

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

That said, the built-in deadlock detector does trigger for the code you've pasted above: https://play.golang.org/p/UvS4MkDtXhx

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 9, 2019

@bcmills at playground, it deadlock. but on my mac, it's not, see the picture below

image

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

@georgehao, the deadlock detector is disabled when the C linker is used (see #29322), and as of Go 1.12, Go on macOS uses the C libSystem for system calls (#17490).

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 9, 2019

@bcmills I see the golang version of playgroud is 1.12.5, it's deadlock. but on my macOS is not. why ?

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

The Playground does not use macOS.

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 9, 2019

I see, when run the code in linux os, the deadlock appeared. That is, golang invokes system calls don't use C lib on linux OS, it invoke direct ?

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

Correct.

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 9, 2019

@bcmills oh, my mistake. I just found that I commented the wrong code. When I run the right code on linux, it also don't has the deadlock. see the below

image

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

That's expected. See #33004 (comment).

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 10, 2019

@bcmills I test on centos, ubuntu with version 1.10, 1.12.5, 1.12.6, 1.12.7 of the code, all don't have the deadlock. but go playground does, it's interesting

@bcmills

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

Whether the deadlock detector triggers may depend on goroutine scheduling and system call implementation details.

Fundamentally, your programs — and tests of those programs — should not rely on the behavior of the deadlock detector. It's a useful tool when it triggers, but it's not an adequate substitute for profiling, integration-testing, and load-testing.

@georgehao

This comment has been minimized.

Copy link
Author

commented Jul 11, 2019

thx @bcmills

@georgehao georgehao closed this Jul 11, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.