title: Can't kill multiprocessing pool in a multithreaded C application embedding Python
body: <p>OS: linux <br>
  Python version: 3.6</p>
  
  <p>I'm trying to extend a C application with Python runtime. The C application uses <code>pthread</code> and I tried to use <code>multiprocessing</code> <code>forkserver</code> in Python runtime but faced a problem. When I try to kill the program with <code>SIGINT</code> signal (by hitting <kbd>Ctrl</kbd>+<kbd>C</kbd> in the terminal) the worker processes get killed but the main program hangs.</p>
  
  <p>Here is a toy program that produces the same problem.</p>
  
  <pre class="lang-c prettyprint-override"><code>#include &lt;Python.h&gt;
  #include &lt;pthread.h&gt;
  
  void * thread_start(void *unsed)
  {
      PyObject *fs_mod = PyImport_AddModule("fs");
      PyObject *apply_fn = PyObject_GetAttrString(fs_mod, "apply");
      PyObject *job_fn = PyObject_GetAttrString(fs_mod, "job");
      PyObject *job_args = Py_BuildValue("()");
      PyObject_CallFunctionObjArgs(apply_fn, job_fn, job_args, NULL);
      printf("finished\n");
      return NULL;
  }
  
  int main(){
      Py_Initialize();
      PyRun_SimpleString(
          "import sys; sys.path.append('...');"
          "sys.argv=['a.out'];"  // prepare a dummy argument to avoid error in forkserver
          "import fs\n"
          "if __name__ == '__main__': fs.init()");
  
      while(1){
          pthread_t thread;
          pthread_create(&amp;thread, 0, &amp;thread_start, NULL);
          printf("joing\n");
          pthread_join(thread, 0);
      }
  }
  </code></pre>
  
  <pre class="lang-py prettyprint-override"><code>import multiprocessing as mp
  
  pool = None
  
  
  def job():
      import time
      print("running..")
      time.sleep(5)
  
  def init():
      global pool
      mp.set_start_method('forkserver')
      pool = mp.Pool(1)
  
  def apply(*args):
      global pool
      return pool.apply(*args)
  </code></pre>
  
  <p>I don't exactly know how Linux signal works. I tried to catch <code>SIGINT</code> signal in the main python process with signal module, but it seems that main it doesn't get to receive the signal. How would I be able to make this application die gracefully on <code>SIGINT</code> without hanging forever?</p>
  
  <hr>
  
  <p>By reading ViKiG answer, I realized that I can first catch the <code>KeyboardInterrupt</code>(or <code>SIGINT</code>) exception in the worker processes and send some sentinel value to the main process to notify the exception and shut down the application.</p>
  
  <p>After skimming through the CPython forkserver implementation, I potentially concluded that the author of the library intentionally made the main process ignore the <code>SIGINT</code>. I guess, currently, that the recommended way is to catch the exception in the worker processes, not in the main one.</p>