-
Notifications
You must be signed in to change notification settings - Fork 140
Goroutine calls Python but deadlocks #49
Comments
As far as I understand, this project is just a relatively thin wrapper around Python's C API. So basically all the limitations of the Python C API apply. One limitation is that Python has a global interpreter lock (GIL). You can't do multiple things in a Python interpreter at the same time (unless you use Python's concurrency features in the Python code that you're executing). The easiest way to make embedded Python to work with goroutines is to make sure that only one goroutine is actually "doing" Python at a time and all the other ones have to wait. Here's an excellent blog post and related conference talk that cover this and a few other options. |
Thank you very much indeed. package main
import (
"sync"
"github.com/sbinet/go-python"
)
func main() {
// The following will also create the GIL explicitly
// by calling PyEval_InitThreads(), without waiting
// for the interpreter to do that
python.Initialize()
var wg sync.WaitGroup
wg.Add(2)
fooModule := python.PyImport_ImportModule("foo")
odds := fooModule.GetAttrString("print_odds")
even := fooModule.GetAttrString("print_even")
// Initialize() has locked the the GIL but at this point we don't need it
// anymore. We save the current state and release the lock
// so that goroutines can acquire it
state := python.PyEval_SaveThread()
go func() {
_gstate := python.PyGILState_Ensure()
odds.Call(python.PyTuple_New(0), python.PyDict_New())
python.PyGILState_Release(_gstate)
wg.Done()
}()
go func() {
_gstate := python.PyGILState_Ensure()
even.Call(python.PyTuple_New(0), python.PyDict_New())
python.PyGILState_Release(_gstate)
wg.Done()
}()
wg.Wait()
// At this point we know we won't need Python anymore in this
// program, we can restore the state and lock the GIL to perform
// the final operations before exiting.
python.PyEval_RestoreThread(state)
python.Finalize()
} There are three steps:
|
Describe what happened:
Does the project support Goroutine?
Recently, I encountered the following problems in the network programming project (simplified version):
.
├── go.mod
├── go.sum
├── hello
│ ├── model
│ │ └── resnet18.pth
│ └── test.py
├── main.go
└── test
test.py
file :main.go
:When I run it, sometimes it works perfectly, but sometimes it blocks python code:
Describe what you expected:
I don't know if this is a problem with multiple goroutine resource preemption or not supporting multithreading, or maybe it's a problem with my go-python3 code.
Because I was writing a network communication project, I had to have multiple goroutine receive and send data (Model) enabled on the same node, and the entire python3 environment remained running until the node was shut down. I'm limited in what I can do, so I'd appreciate it if you could take a look
The text was updated successfully, but these errors were encountered: