I have a Python app that calls a C++ boost python library and it all works. However, I have a callback C++ to Python scenario where C++ from a boost thread calls python and I get an access violation on the C++ side. If I do exactly the same callback using the python thread it works perfectly. Therefore I suspect that I can not simply callback Python from C++ using a boost thread but need to do something extra for it to work?
Related Questions in PYTHON
- php Variable name must change in for loop
- register_shutdown_function is not getting called
- Query returning zero rows despite entries existing
- Retrieving *number* pages by page id
- Automatically closing tags in form input?
- How to resize images with PHP PARSE SDK
- how to send email from localhost using codeigniter?
- Mariadb max Error while sending QUERY packet PID
- Multiusers login redirect different page in php
- Imaginary folder when I use "DirectoryIterator" in PHP?
Related Questions in C++
- php Variable name must change in for loop
- register_shutdown_function is not getting called
- Query returning zero rows despite entries existing
- Retrieving *number* pages by page id
- Automatically closing tags in form input?
- How to resize images with PHP PARSE SDK
- how to send email from localhost using codeigniter?
- Mariadb max Error while sending QUERY packet PID
- Multiusers login redirect different page in php
- Imaginary folder when I use "DirectoryIterator" in PHP?
Related Questions in MULTITHREADING
- php Variable name must change in for loop
- register_shutdown_function is not getting called
- Query returning zero rows despite entries existing
- Retrieving *number* pages by page id
- Automatically closing tags in form input?
- How to resize images with PHP PARSE SDK
- how to send email from localhost using codeigniter?
- Mariadb max Error while sending QUERY packet PID
- Multiusers login redirect different page in php
- Imaginary folder when I use "DirectoryIterator" in PHP?
Related Questions in BOOST-PYTHON
- php Variable name must change in for loop
- register_shutdown_function is not getting called
- Query returning zero rows despite entries existing
- Retrieving *number* pages by page id
- Automatically closing tags in form input?
- How to resize images with PHP PARSE SDK
- how to send email from localhost using codeigniter?
- Mariadb max Error while sending QUERY packet PID
- Multiusers login redirect different page in php
- Imaginary folder when I use "DirectoryIterator" in PHP?
Related Questions in BOOST-THREAD
- php Variable name must change in for loop
- register_shutdown_function is not getting called
- Query returning zero rows despite entries existing
- Retrieving *number* pages by page id
- Automatically closing tags in form input?
- How to resize images with PHP PARSE SDK
- how to send email from localhost using codeigniter?
- Mariadb max Error while sending QUERY packet PID
- Multiusers login redirect different page in php
- Imaginary folder when I use "DirectoryIterator" in PHP?
Popular Questions
- How do I undo the most recent local commits in Git?
- How can I remove a specific item from an array in JavaScript?
- How do I delete a Git branch locally and remotely?
- Find all files containing a specific text (string) on Linux?
- How do I revert a Git repository to a previous commit?
- How do I create an HTML button that acts like a link?
- How do I check out a remote Git branch?
- How do I force "git pull" to overwrite local files?
- How do I list all files of a directory?
- How to check whether a string contains a substring in JavaScript?
- How do I redirect to another webpage?
- How can I iterate over rows in a Pandas DataFrame?
- How do I convert a String to an int in Java?
- Does Python have a string 'contains' substring method?
- How do I check if a string contains a specific word?
Popular Tags
Trending Questions
- UIImageView Frame Doesn't Reflect Constraints
- Is it possible to use adb commands to click on a view by finding its ID?
- How to create a new web character symbol recognizable by html/javascript?
- Why isn't my CSS3 animation smooth in Google Chrome (but very smooth on other browsers)?
- Heap Gives Page Fault
- Connect ffmpeg to Visual Studio 2008
- Both Object- and ValueAnimator jumps when Duration is set above API LvL 24
- How to avoid default initialization of objects in std::vector?
- second argument of the command line arguments in a format other than char** argv or char* argv[]
- How to improve efficiency of algorithm which generates next lexicographic permutation?
- Navigating to the another actvity app getting crash in android
- How to read the particular message format in android and store in sqlite database?
- Resetting inventory status after order is cancelled
- Efficiently compute powers of X in SSE/AVX
- Insert into an external database using ajax and php : POST 500 (Internal Server Error)
The most likely culprit is that the Global Interpreter Lock (GIL) is not being held by a thread when it is invoking Python code, resulting in undefined behavior. Verify all paths that make direct or indirect Python calls, acquire the GIL before invoking Python code.
The GIL is a mutex around the CPython interpreter. This mutex prevents parallel operations to be performed on Python objects. Thus, at any point in time, a max of one thread, the one that has acquired the GIL, is allowed to perform operations on Python objects. When multiple threads are present, invoking Python code whilst not holding the GIL results in undefined behavior.
C or C++ threads are sometimes referred to as alien threads in the Python documentation. The Python interpreter has no ability to control the alien thread. Therefore, alien threads are responsible for managing the GIL to permit concurrent or parallel execution with Python threads. One must meticulously consider:
One solution is to wrap Python callbacks with a custom type that is aware of GIL management.
Using a RAII-style class to manage the GIL provides an elegant exception-safe solution. For example, with the following
with_gil
class, when awith_gil
object is created, the calling thread acquires the GIL. When thewith_gil
object is destructed, it restores the GIL state.And its usage:
With being able to manage the GIL via
with_gil
, the next step is to create a functor that properly manages the GIL. The followingpy_callable
class will wrap aboost::python::object
and acquire the GIL for all paths in which Python code is invoked:By managing the
boost::python::object
on the free-space, one can freely copy theshared_ptr
without having to hold the GIL. This allows for us to safely use the default generated copy-constructor, assignment operator, destructor, etc.One would use the
py_callable
as follows:Here is a complete example demonstrating having a Python extension invoke a Python object as a callback from a C++ thread:
Interactive usage: