title: Python GIL and threads
body: <p>I have embedded Python3 in my big C++ application. Python gives the user script capability for custom data processing.<br>
  <strong>Problem</strong> : I have many threads that interact with Python and I don't really get how to protect my code with GIL. So far, the only way I made my code work is using <code>boost::mutex</code>.  </p>
  
  <p>Here is a very simplified example that reproduces my problem: </p>
  
  <ul>
  <li>Thread A calls first <code>Init()</code> to initialize Python (static function).</li>
  <li>Thread B calls <code>Pythonize()</code> to do some work on Python. Thread B is blocked on the first call for locking GIL.</li>
  </ul>
  
  <p><em>Code</em>:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;boost/thread.hpp&gt;
  #include &lt;boost/bind.hpp&gt;
  
  #include "Python.h"
  
  struct RTMaps_GILLock
  {
      RTMaps_GILLock()
      {
          std::cout &lt;&lt; "Locking..." &lt;&lt; std::endl;
          m_state = PyGILState_Ensure();
      }
  
      ~RTMaps_GILLock()
      {
          std::cout &lt;&lt; "Unlocking..." &lt;&lt; std::endl;
          PyGILState_Release(m_state);
      }
  
  private:
      PyGILState_STATE m_state;
  };
  #define GILLOCK RTMaps_GILLock lock;
  
  class PythonEmbed
  {
  public:
      static void Init()
      {
          Py_Initialize();
          // EDIT : adding those two lines made my day :
          PyEval_InitThreads(); // This acquires GIL
          PyEval_SaveThread(); // Release the GIL
      }
  
      void Pythonize()
      {
          GILLOCK;
          // Never goes here :(
          std::cout &lt;&lt; "OK" &lt;&lt; std::endl;
      }
  };
  
  int main()
  {
      PythonEmbed::Init();
  
      PythonEmbed pyt;
      boost::thread t(boost::bind(&amp;PythonEmbed::Pythonize, pyt));
  
      t.join();
  }
  </code></pre>
  
  <p>it is deadlocking in the first lock call. The console shows:
      Locking...</p>
  
  <p>The "OK" is never printed. What am I doing wrong ?</p>
  
  <p>EDIT :  corrected code, now it is working. I needed to release the GIL from the main thread.</p>