title: Call python in parallel from C
body: <p>I need to call a Python function from my C code.
  It works perfectly, but when I want to do parallelization, it breaks down.
  Please see the following minimal C code:</p>
  
  <pre><code>#include &lt;Python.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(void)
  {
    double Z = 1.;
    double k = 1.;
    double l = 1.;
    double eta = -Z/k;
  
    Py_Initialize();
  
    PyObject* pName = PyString_FromString("mpmath");
    PyObject* pModule = PyImport_Import(pName);
    PyObject* pFunc = PyObject_GetAttrString(pModule, "coulombf");
  
    PyObject* pl = PyFloat_FromDouble(l);
    PyObject* peta = PyFloat_FromDouble(eta);
  
    int i;
  #pragma omp parallel for private(i)
    for(i=0; i&lt;10000; i++)
    {
      double r = 0.01*i;
      PyObject* prho = PyFloat_FromDouble(k*r);
      PyObject* pArgs = PyTuple_Pack(3, pl, peta, prho);
      PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
      double value = PyFloat_AsDouble(pValue);
      printf("r=%.2f\tf=%.6f\n",r,value);
    }
  
    Py_Finalize();
    return 0;
  }
  </code></pre>
  
  <p>Let's name this file as <code>testPython.c</code>, you can compile it with <code>gcc -fopenmp testPython.c -o testPython -I/usr/include/python2.7 -L/usr/lib64/python2.7/config -lpython2.7</code>.</p>
  
  <p>Now run it with <code>./testPython</code>, you with see such error: <code>Fatal Python error: GC object already tracked</code>. (Sometimes, the error info differs.)</p>
  
  <p>But if you compile it leaving <code>-fopenmp</code> out, the program works perfectly.</p>
  
  <p>How can I overcome this problem? Thanks!</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>As answered by Natecat, John Bollinger, and Olaf, multithreading is unlikely to speed up the process much, but multiprocessing can really speed up the computation. The pure python script is as simple as following:</p>
  
  <pre><code>import numpy
  from mpmath import coulombf
  from multiprocessing import Pool
  
  Z = 1.
  k = 1.
  l = 1.
  eta = -Z/k
  
  def coulombF(r):
      return coulombf(l,eta,k*r)
  
  pool = Pool(12)
  result = pool.map_async(coulombF, numpy.arange(0.,100.,0.01))
  print(result.get())
  </code></pre>
  
  <p>But how do I do it in C? I haven't found the way yet.</p>