<p>I've been trying to wrap my head around how threads work in Python, and it's hard to find good information on how they operate. I may just be missing a link or something, but it seems like the official documentation isn't very thorough on the subject, and I haven't been able to find a good write-up.</p>

<p>From what I can tell, only one thread can be running at once, and the active thread switches every 10 instructions or so?</p>

<p>Where is there a good explanation, or can you provide one? It would also be very nice to be aware of common problems that you run into while using threads with Python.</p>

[{'answer_id': 31358, 'author': 'mmattax', 'author_id': 1638, 'author_profile': 'https://Stackoverflow.com/users/1638', 'pm_score': 4, 'selected': False, 'text': '<p>Below is a basic threading sample. It will spawn 20 threads; each thread will output its thread number. Run it and observe the order in which they print.</p>\n\n<pre><code>import threading\nclass Foo (threading.Thread):\n    def __init__(self,x):\n        self.__x = x\n        threading.Thread.__init__(self)\n    def run (self):\n          print str(self.__x)\n\nfor x in xrange(20):\n    Foo(x).start()\n</code></pre>\n\n<p>As you have hinted at Python threads are implemented through time-slicing. This is how they get the "parallel" effect. </p>\n\n<p>In my example my Foo class extends thread, I then implement the <code>run</code> method, which is where the code that you would like to run in a thread goes. To start the thread you call <code>start()</code> on the thread object, which will automatically invoke the <code>run</code> method...</p>\n\n<p>Of course, this is just the very basics. You will eventually want to learn about semaphores, mutexes, and locks for thread synchronization and message passing.</p>\n'}, {'answer_id': 31372, 'author': 'Jason Baker', 'author_id': 2147, 'author_profile': 'https://Stackoverflow.com/users/2147', 'pm_score': 5, 'selected': False, 'text': '<p>Python\'s a fairly easy language to thread in, but there are caveats.  The biggest thing you need to know about is the Global Interpreter Lock.  This allows only one thread to access the interpreter.  This means two things:  1)  you rarely ever find yourself using a lock statement in python and 2) if you want to take advantage of multi-processor systems, you have to use separate processes.  EDIT:  I should also point out that you can put some of the code in C/C++ if you want to get around the GIL as well.</p>\n\n<p>Thus, you need to re-consider why you want to use threads.  If you want to parallelize your app to take advantage of dual-core architecture, you need to consider breaking your app up into multiple processes.</p>\n\n<p>If you want to improve responsiveness, you should CONSIDER using threads.  There are other alternatives though, namely <a href="http://en.wikipedia.org/wiki/Microthread" rel="noreferrer">microthreading</a>.  There are also some frameworks that you should look into:</p>\n\n<ul>\n<li><a href="http://www.stackless.com/" rel="noreferrer">stackless python</a></li>\n<li><a href="http://greenlet.readthedocs.org/en/latest/" rel="noreferrer">greenlets</a></li>\n<li><a href="http://www.gevent.org/" rel="noreferrer">gevent</a></li>\n<li><a href="https://github.com/saucelabs/monocle" rel="noreferrer">monocle</a></li>\n</ul>\n'}, {'answer_id': 31398, 'author': 'Peter Hoffmann', 'author_id': 720, 'author_profile': 'https://Stackoverflow.com/users/720', 'pm_score': 7, 'selected': True, 'text': '<p>Yes, because of the Global Interpreter Lock (GIL) there can only run one thread at a time. Here are some links with some insights about this:</p>\n\n<ul>\n<li><a href="http://www.artima.com/weblogs/viewpost.jsp?thread=214235" rel="noreferrer">http://www.artima.com/weblogs/viewpost.jsp?thread=214235</a></li>\n<li><a href="http://smoothspan.wordpress.com/2007/09/14/guido-is-right-to-leave-the-gil-in-python-not-for-multicore-but-for-utility-computing/" rel="noreferrer">http://smoothspan.wordpress.com/2007/09/14/guido-is-right-to-leave-the-gil-in-python-not-for-multicore-but-for-utility-computing/</a></li>\n</ul>\n\n<p>From the last link an interesting quote:</p>\n\n<blockquote>\n  <p>Let me explain what all that means. \n  Threads run inside the same virtual\n  machine, and hence run on the same\n  physical machine.  Processes can run\n  on the same physical machine or in\n  another physical machine.  If you\n  architect your application around\n  threads, you’ve done nothing to access\n  multiple machines.  So, you can scale\n  to as many cores are on the single\n  machine (which will be quite a few\n  over time), but to really reach web\n  scales, you’ll need to solve the\n  multiple machine problem anyway.</p>\n</blockquote>\n\n<p>If you want to use multi core, <a href="http://www.python.org/dev/peps/pep-0371/" rel="noreferrer">pyprocessing</a> defines an process based API to do real parallelization. The <a href="http://en.wikipedia.org/wiki/Python_Enhancement_Proposal#Development" rel="noreferrer">PEP</a> also includes some interesting benchmarks.</p>\n'}, {'answer_id': 31552, 'author': 'Ben McNiel', 'author_id': 1455, 'author_profile': 'https://Stackoverflow.com/users/1455', 'pm_score': 4, 'selected': False, 'text': '<p>Use threads in python if the individual workers are doing I/O bound operations. If you are trying to scale across multiple cores on a machine either find a good <a href="http://www.python.org/dev/peps/pep-0371/" rel="noreferrer">IPC</a> framework for python or pick a different language.</p>\n'}, {'answer_id': 1197151, 'author': 'phreaki', 'author_id': 121718, 'author_profile': 'https://Stackoverflow.com/users/121718', 'pm_score': 2, 'selected': False, 'text': '<p>Try to remember that the GIL is set to poll around every so often in order to do show the appearance of multiple tasks. This setting can be fine tuned, but I offer the suggestion that there should be work that the threads are doing or lots of context switches are going to cause problems.</p>\n\n<p>I would go so far as to suggest multiple parents on processors and try to keep like jobs on the same core(s).</p>\n'}, {'answer_id': 21608282, 'author': 'willt', 'author_id': 3280431, 'author_profile': 'https://Stackoverflow.com/users/3280431', 'pm_score': 2, 'selected': False, 'text': '<p>One easy solution to the GIL is the <a href="http://docs.python.org/2/library/multiprocessing.html" rel="nofollow" title="Python docs link">multiprocessing</a> module. It can be used as a drop in replacement to the threading module but uses multiple Interpreter processes instead of threads. Because of this there is a little more overhead than plain threading for simple things but it gives you the advantage of real parallelization if you need it.\nIt also easily scales to multiple physical machines.</p>\n\n<p>If you need truly large scale parallelization than I would look further but if you just want to scale to all the cores of one computer or a few different ones without all the work that would go into implementing a more comprehensive framework, than this is for you.</p>\n'}, {'answer_id': 49573860, 'author': 'anekix', 'author_id': 6518118, 'author_profile': 'https://Stackoverflow.com/users/6518118', 'pm_score': 4, 'selected': False, 'text': '<p><strong>Note:</strong>  wherever I mention <code>thread</code> i mean specifically <strong><em>threads in python</em></strong> until explicitly stated.</p>\n\n<p>Threads work a little differently in python if you are coming from <code>C/C++</code> background. In python, Only one thread can be in running state at a given time.This means Threads in python cannot truly leverage the power of multiple processing cores since by design it\'s not possible for threads to run parallelly on multiple cores.</p>\n\n<p>As the memory management in python is not thread-safe each thread require an exclusive access to data structures in python interpreter.This exclusive access is acquired by a mechanism called <strong><em><code>GIL</code></em></strong> <em>( global interpretr lock )</em>.</p>\n\n<p><strong><code>Why does python use GIL?</code></strong></p>\n\n<p>In order to prevent multiple threads from accessing interpreter state simultaneously and corrupting the interpreter state.</p>\n\n<p>The idea is whenever a thread is being executed <em>(even if it\'s the main thread)</em>, a GIL is acquired and after some predefined interval of time the \nGIL is released by the current thread and reacquired by some other thread( if any).</p>\n\n<p><strong><code>Why not simply remove GIL?</code></strong></p>\n\n<p>It is not that its impossible to remove GIL,  its just that in prcoess of doing so we end up putting mutiple locks inside interpreter in order to serialize access, which makes even a single threaded application less performant.</p>\n\n<p>so the cost of removing GIL is paid off by reduced performance of a single threaded application, which is never desired.</p>\n\n<p><strong><code>So when does thread switching occurs in python?</code></strong></p>\n\n<p>Thread switch occurs when GIL is released.So when is GIL Released?\nThere are two scenarios to take into consideration.</p>\n\n<p><strong><em>If a Thread is doing CPU Bound operations(Ex image processing).</em></strong></p>\n\n<p>In Older versions of python , Thread switching used to occur after a fixed no of python instructions.It was by default set to <strong><code>100</code></strong>.It turned out that its not a very good policy to decide when switching should occur since the time spent executing a single instruction can\nvery wildly from millisecond to even a second.Therefore releasing GIL after every <strong><code>100</code></strong> instructions regardless of the time they take to execute is a poor policy.</p>\n\n<p>In new versions instead of using instruction count as a metric to switch thread ,  a configurable time interval is used. \nThe default switch interval is 5 milliseconds.you can get the current switch interval using <a href="https://docs.python.org/3/library/sys.html#sys.getswitchinterval" rel="noreferrer"><strong><em><code>sys.getswitchinterval()</code></em></strong></a>.\nThis can be altered using <a href="https://docs.python.org/3/library/sys.html#sys.setswitchinterval" rel="noreferrer"><strong><em><code>sys.setswitchinterval()</code></em></strong></a></p>\n\n<p><strong><em>If a Thread is doing some IO Bound Operations(Ex filesystem access or<br>\n    network IO)</em></strong></p>\n\n<p>GIL is release whenever the thread is waiting for some for IO operation to get completed.</p>\n\n<p><strong><code>Which thread to switch to next?</code></strong></p>\n\n<p>The interpreter doesn’t have its own scheduler.which thread becomes scheduled at the end of the interval is the operating system’s decision. .</p>\n'}]
['https://Stackoverflow.com/questions/31340', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/242853/']