Skip to content

cgo: goroutine scheduler stops working after fork #53806

@spacewander

Description

@spacewander

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

$ go version
go version go1.17.1 linux/amd64

Does this issue reproduce with the latest release?

Not sure

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/lzx/.cache/go-build"
GOENV="/home/lzx/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/lzx/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/lzx/go"
GOPRIVATE=""
GOPROXY="https://goproxy.cn"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.1"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
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=/tmp/go-build684821102=/tmp/go-build -gno-record-gcc-switches"

What did you do?

When I try to call Go code in C, I figure out that the goroutine scheduler will stop working in the child process.

What did you expect to see?

Here is a minimal example:

The C code which calls the Go code:

#include <unistd.h>
#include <stdio.h>
#include "libcgo.h"

int main(int argc, char *argv[])
{
    call();
    printf("back\n");
    usleep(1000 * 1000);

    pid_t pid = fork();

    switch (pid) {

    case 0:
        printf("child\n");
        call();
        printf("back\n");
        usleep(1000 * 1000);

    default:
        break;
    }

    return 0;
}

The Go code:

package main

/*
#cgo LDFLAGS: -shared -ldl -lpthread
#include <stdlib.h>
*/
import "C"
import (
        //"time"
)

func main() {
}

//export call
func call() {
        go func() {
                println("AC")
        }()
        //time.Sleep(time.Second)
}

Compile the Go code with go build -o libcgo.so -buildmode=c-shared *.go.
Then compile the C code with clang -L. -lcgo main.c. After that, run ./a.out.

I expected to see:

back
AC
child
back
AC

One of the "AC" is from the parent, and the other is from the child.

What did you see instead?

back
AC
child
back

The goroutine spawned in the child process's C code is not scheduled.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions