your C interface More precise in C header Merge multiple Cgo calls into 1 Do loop-calls in C is more efficient foos := []C.struct_Foo{ { a: C.int(1), b: C.int(2) }, { a: C.int(3), b: C.int(4) }, } C.pass_array((*C.struct_Foo)(unsafe.Pointer(&foos[0])), C.int(len(foos)))
ownership Use "defer C.free()" to release memory when func returns d := C.GoBytes([]byte{...}) C.foo(d) // <- if foo() takes the ownership // C.free(d)
main() { var wg sync.WaitGroup wg.Add(1000) for i := 0; i < 1000; i++ { go func() { time.Sleep(100 * time.Second) wg.Done() }() } wg.Wait() } func main() { var wg sync.WaitGroup wg.Add(1000) for i := 0; i < 1000; i++ { go func() { time.Sleep(100 * time.Second) wg.Done() }() } wg.Wait() } // use 13 threads // use 1004 threads
cgocall(fn, arg unsafe.Pointer) int32 { ... // Announce we are entering a system call // so that the scheduler knows to create another // M to run goroutines while we are in the // foreign code. // entersyscall() errno := asmcgocall(fn, arg) exitsyscall() ... }