title: On what CPU cores are my Python processes running?
body: <p><strong>The setup</strong></p>
  
  <p>I have written a pretty complex piece of software in Python (on a Windows PC). My software starts basically two Python interpreter shells. The first shell starts up (I suppose) when you double click the <code>main.py</code> file. Within that shell, other threads are started in the following way:</p>
  
  <pre><code>    # Start TCP_thread
      TCP_thread = threading.Thread(name = 'TCP_loop', target = TCP_loop, args = (TCPsock,))
      TCP_thread.start()
  
      # Start UDP_thread
      UDP_thread = threading.Thread(name = 'UDP_loop', target = UDP_loop, args = (UDPsock,))
      TCP_thread.start()
  </code></pre>
  
  <p>The <code>Main_thread</code> starts a <code>TCP_thread</code> and a <code>UDP_thread</code>. Although these are separate threads, they all run within one single Python shell.</p>
  
  <p>The <code>Main_thread</code>also starts a subprocess. This is done in the following way:</p>
  
  <pre><code>p = subprocess.Popen(['python', mySubprocessPath], shell=True)
  </code></pre>
  
  <p>From the Python documentation, I understand that this subprocess is running <em>simultaneously (!)</em> in a separate Python interpreter session/shell. The <code>Main_thread</code>in this subprocess is completely dedicated to my GUI. The GUI starts a <code>TCP_thread</code> for all its communications.</p>
  
  <p>I know that things get a bit complicated. Therefore I have summarized the whole setup in this figure:</p>
  
  <p><a href="https://i.stack.imgur.com/XFN5o.png"><img src="https://i.stack.imgur.com/XFN5o.png" alt="enter image description here"></a></p>
  
  <hr>
  
  <p>I have several questions concerning this setup. I will list them down here:</p>
  
  <p><strong>Question 1</strong>  [<em>Solved</em>]</p>
  
  <p>Is it true that a Python interpreter uses only one CPU core at a time to run all the threads? In other words, will the <code>Python interpreter session 1</code> (from the figure) run all 3 threads (<code>Main_thread</code>, <code>TCP_thread</code> and <code>UDP_thread</code>) on one CPU core?</p>
  
  <p><em>Answer: yes, this is true. The GIL (Global Interpreter Lock) ensures that all threads run on one CPU core at a time.</em></p>
  
  <p><strong>Question 2</strong>  [<em>Not yet solved</em>]</p>
  
  <p>Do I have a way to track which CPU core it is?</p>
  
  <p><strong>Question 3</strong>  [<em>Partly solved</em>]</p>
  
  <p>For this question we forget about <em>threads</em>, but we focus on the <em>subprocess</em> mechanism in Python. Starting a new subprocess implies starting up a new Python interpreter <strong>instance</strong>. Is this correct?</p>
  
  <p><em>Answer: Yes this is correct. At first there was some confusion about whether the following code would create a new Python interpreter instance:</em></p>
  
  <pre><code>    p = subprocess.Popen(['python', mySubprocessPath], shell = True)
  </code></pre>
  
  <p><em>The issue has been clarified. This code indeed starts a new Python interpreter instance.</em></p>
  
  <p>Will Python be smart enough to make that separate Python interpreter instance run on a different CPU core? Is there a way to track which one, perhaps with some sporadic print statements as well?</p>
  
  <p><strong>Question 4</strong>   [<em>New question</em>]</p>
  
  <p>The community discussion raised a new question. There are apparently two approaches when spawning a new process (within a new Python interpreter instance):</p>
  
  <pre><code>    # Approach 1(a)
      p = subprocess.Popen(['python', mySubprocessPath], shell = True)
  
      # Approach 1(b) (J.F. Sebastian)
      p = subprocess.Popen([sys.executable, mySubprocessPath])
  
      # Approach 2
      p = multiprocessing.Process(target=foo, args=(q,))
  </code></pre>
  
  <p>The second approach has the obvious downside that it targets just a function - whereas I need to open up a new Python script. Anyway, are both approaches similar in what they achieve?</p>