Last active
August 29, 2023 15:41
-
-
Save sterin/e8090d0451ab781a4e22 to your computer and use it in GitHub Desktop.
Example for stackoverflow.com question http://stackoverflow.com/questions/29595222/multithreading-with-python-and-c-api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 2.8.4) | |
project(so29595222) | |
find_package(PythonLibs REQUIRED) | |
include_directories(${PYTHON_INCLUDE_DIRS}) | |
ADD_DEFINITIONS( -std=c++11 ) | |
set(SOURCE_FILES python_threading_example_so29595222.cpp) | |
add_executable(so29595222 ${SOURCE_FILES}) | |
target_link_libraries(so29595222 ${PYTHON_LIBRARIES}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Author: Baruch Sterin <baruchs@gmail.com> | |
#include <Python.h> | |
#include <thread> | |
#include <chrono> | |
// initialize and clean up python | |
struct initialize | |
{ | |
initialize() | |
{ | |
Py_InitializeEx(1); | |
PyEval_InitThreads(); | |
} | |
~initialize() | |
{ | |
Py_Finalize(); | |
} | |
}; | |
// acquire GIL | |
class ensure_gil_state | |
{ | |
public: | |
ensure_gil_state() | |
{ | |
_state = PyGILState_Ensure(); | |
} | |
~ensure_gil_state() | |
{ | |
PyGILState_Release(_state); | |
} | |
private: | |
PyGILState_STATE _state; | |
}; | |
// allow other threads to run | |
class enable_threads | |
{ | |
public: | |
enable_threads() | |
{ | |
_state = PyEval_SaveThread(); | |
} | |
~enable_threads() | |
{ | |
PyEval_RestoreThread(_state); | |
} | |
private: | |
PyThreadState* _state; | |
}; | |
char program[] = | |
"import threading\n" | |
"def loop():\n" | |
" for i in xrange(25):\n" | |
" import time\n" | |
" print \'.\'\n" | |
" time.sleep(0.1)\n" | |
"t = threading.Thread(target=loop)\n" | |
"t.start()\n" | |
; | |
// run in a new thread | |
void f() | |
{ | |
{ | |
// grab the GIL | |
ensure_gil_state gil_scope; | |
// run the Python code above | |
PyRun_SimpleString(program); | |
} | |
// let the thread sleep a bit | |
std::this_thread::sleep_for(std::chrono::seconds(1)); | |
} | |
int main() | |
{ | |
// initialize Python with thread support | |
initialize init; | |
// start the new thread | |
std::thread t(f); | |
{ | |
// release the GIL | |
enable_threads enable_threads_scope; | |
// wait for the thread to terminate | |
t.join(); | |
} | |
// wait for the Python thread to terminate | |
PyRun_SimpleString("t.join()"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment