diff --git a/include/dynamic-graph/python/interpreter.hh b/include/dynamic-graph/python/interpreter.hh
index 2c49695c5121e62841a16b4d119f4d23ed97ea69..e71168532e7679e6ac64fc59d2385ec2c9b2fdba 100644
--- a/include/dynamic-graph/python/interpreter.hh
+++ b/include/dynamic-graph/python/interpreter.hh
@@ -62,6 +62,8 @@ namespace dynamicgraph {
       PyObject* globals();
 
     private:
+      /// The Pythone thread state
+      PyThreadState *_pyState;
       /// Pointer to the dictionary of global variables
       PyObject* globals_;
       /// Pointer to the dictionary of local variables
diff --git a/src/interpreter.cc b/src/interpreter.cc
index 373d5baab27159ac43c7561e2eaaa79a433829bd..b2c4cc8cf564a87134651fb3c9dbcbe8b91763c0 100644
--- a/src/interpreter.cc
+++ b/src/interpreter.cc
@@ -139,6 +139,7 @@ Interpreter::Interpreter()
   dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL);
 #endif
   Py_Initialize();
+  PyEval_InitThreads();
   mainmod_ = PyImport_AddModule("__main__");
   Py_INCREF(mainmod_);
   globals_ = PyModule_GetDict(mainmod_);
@@ -155,10 +156,14 @@ Interpreter::Interpreter()
       (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception");
   assert(PyCallable_Check(traceback_format_exception_));
   Py_INCREF(traceback_format_exception_);
+
+  // Allow threads
+  _pyState = PyEval_SaveThread();
 }
 
 Interpreter::~Interpreter()
 {
+  PyEval_RestoreThread(_pyState);
   //Py_DECREF(mainmod_);
   //Py_DECREF(globals_);
   //Py_DECREF(traceback_format_exception_);
@@ -180,6 +185,8 @@ void Interpreter::python( const std::string& command, std::string& res,
   out = "";
   err = "";
 
+  PyEval_RestoreThread(_pyState);
+
   std::cout << command.c_str() << std::endl;
   PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_,
                                   globals_);
@@ -234,6 +241,9 @@ void Interpreter::python( const std::string& command, std::string& res,
   Py_DecRef(stdout_obj);
   Py_DecRef(result2);
   Py_DecRef(result);
+
+  _pyState = PyEval_SaveThread();
+
   return;
 }
 
@@ -257,6 +267,8 @@ void Interpreter::runPythonFile( std::string filename, std::string& err)
     return;
   }
 
+  PyEval_RestoreThread(_pyState);
+
   err = "";
   PyObject* pymainContext = globals_;
   PyObject* run = PyRun_FileExFlags(pFile, filename.c_str(),
@@ -268,12 +280,16 @@ void Interpreter::runPythonFile( std::string filename, std::string& err)
     std::cerr << err << std::endl;;
   }
   Py_DecRef(run);
+
+  _pyState = PyEval_SaveThread();
 }
 
 void Interpreter::runMain( void )
 {
   const char * argv [] = { "dg-embedded-pysh" };
+  PyEval_RestoreThread(_pyState);
   Py_Main(1,const_cast<char**>(argv));
+  _pyState = PyEval_SaveThread();
 }
 
 std::string Interpreter::processStream(std::istream& stream, std::ostream& os)
diff --git a/src/signal-wrapper.hh b/src/signal-wrapper.hh
index 5f26d02c25b0f6e92e978e56820309bf2fa53cb0..b9572ced9d96eaf568caca5c147106452b53b7c2 100644
--- a/src/signal-wrapper.hh
+++ b/src/signal-wrapper.hh
@@ -72,6 +72,11 @@ namespace dynamicgraph {
       private:
         T& call (T& value, Time t)
         {
+          PyGILState_STATE gstate;
+          gstate = PyGILState_Ensure();
+          if (PyGILState_GetThisThreadState() == NULL) {
+            dgDEBUG(10) << "python thread not initialized" << std::endl;
+          }
           char format[] = "i";
           PyObject* obj = PyObject_CallFunction(callable, format, t);
           if (obj == NULL)
@@ -80,6 +85,7 @@ namespace dynamicgraph {
             signalWrapper::convert (obj, value);
             Py_DECREF(obj);
           }
+          PyGILState_Release (gstate);
           return value;
         }
         PyObject* callable;