I'm a new programmer looking for an accessible introduction to multiprocessing and concurrency in pyhton. I'd like an explanation that includes an explanation of the differences between multithreading and multiprocessing
https://realpython.com/lessons/concurrency/
Concurrency – Real Python
2020-12-08
Real Python
<div><div>
 
 
<p>
 
 <a href="#t=0.48"><strong>00:00</strong></a>
 
 
 <a href="#t=0.48">In the previous lesson,</a> <a href="#t=1.589">I talked about the degrees of latency in the different components of your</a> <a href="#t=4.86">computer. In this lesson,</a> <a href="#t=6.75">I’m going to show you how that’s taken advantage of to create concurrency.</a>
</p>
<p>
 
 <a href="#t=11.94"><strong>00:11</strong></a>
 
 
 <a href="#t=11.94">Recall this diagram from the previous lesson.</a> <a href="#t=14.55">It’s common for a program to have to wait long periods of time for it</a> <a href="#t=18.54">to be able to do the next instruction.</a>
</p>
<p>
 
 <a href="#t=21.21"><strong>00:21</strong></a>
 
 
 <a href="#t=21.21">It needs to wait on RAM, disk, and network. Time</a> <a href="#t=24.87">slicing is the idea of the operating system</a> <a href="#t=27.51">mixing other programs into these wait states. While you’re waiting for that</a> <a href="#t=32.34">network packet to come back from Prague,</a> <a href="#t=34.95">the computer can insert multiple other programs to take advantage of that time.</a>
</p>
<p>
 
 <a href="#t=40.77"><strong>00:40</strong></a>
 
 
 <a href="#t=40.77">This time slicing is how a single processor computer can look like it’s doing</a> <a href="#t=45.12">multiple things at the same time.</a>
</p>
<p>
 
 <a href="#t=48.72"><strong>00:48</strong></a>
 
 
 <a href="#t=48.72">Time slicing for multitasking can be thought of at three levels.</a> <a href="#t=52.41">The lowest level is not having any at all. The olden days of personal computers,</a> <a href="#t=57.24">the DOS operating system worked this way.</a>
</p>
<p>
 
 <a href="#t=59.49"><strong>00:59</strong></a>
 
 
 <a href="#t=59.49">You could only run a single program at a time.</a> <a href="#t=63.15">Cooperative multitasking is when the program willingly gives up the CPU.</a> <a href="#t=67.56">If you know that you’re about to go out to the network and you’re not going to</a> <a href="#t=70.35">need the CPU for a while,</a> <a href="#t=71.73">you signal the operating system and the operating system can schedule a</a> <a href="#t=75.27">different program. In home computing, Windows 3.1</a> <a href="#t=78.84">introduced this kind of multitasking.</a>
</p>
<p>
 
 <a href="#t=81.81"><strong>01:21</strong></a>
 
 
 <a href="#t=81.81">If you happen to be old enough to remember using this operating system,</a> <a href="#t=85.14">you may recall that at certain times the program would just stop refreshing.</a> <a href="#t=89.94">That would be because it didn’t give up the CPU,</a> <a href="#t=92.61">but it was stuck in a wait state,</a> <a href="#t=94.65">so the UI was not being updated because the program had not told the operating</a> <a href="#t=99.36">system to put it into the wait state. As the name implies,</a> <a href="#t=103.62">cooperative multitasking requires all of the processes to cooperate with each</a> <a href="#t=107.55">other. In shared computing, or in the case of a program with a problem,</a> <a href="#t=112.2">this can be a challenge.</a>
</p>
<p>
 
 <a href="#t=114.75"><strong>01:54</strong></a>
 
 
 <a href="#t=114.75">So preemptive multitasking was created. The operating system, in this case,</a> <a href="#t=119.37">interrupts the program whether or not it’s ready.</a> <a href="#t=122.7">The operating system is responsible for swapping between the different programs.</a>
</p>
<p>
 
 <a href="#t=127.77"><strong>02:07</strong></a>
 
 
 <a href="#t=127.77">In most operating systems, this is done intelligently.</a> <a href="#t=130.77">If your program does do a network call, that triggers the operating system to</a> <a href="#t=134.91">take advantage of it and put the program into a wait state.</a>
</p>
<p>
 
 <a href="#t=138.57"><strong>02:18</strong></a>
 
 
 <a href="#t=138.57">But it can also do it in the case where the program is being a hog</a> <a href="#t=141.63">and hasn’t given up the CPU.</a>
</p>
<p>
 
 <a href="#t=144.39"><strong>02:24</strong></a>
 
 
 <a href="#t=144.39">Mainframes have done this from very early on, as has Unix. In the Windows world,</a> <a href="#t=149.64">NT and Windows 95 is where preemptive multitasking was first introduced.</a>
</p>
<p>
 
 <a href="#t=156.09"><strong>02:36</strong></a>
 
 
 <a href="#t=156.09">On larger computers,</a> <a href="#t=157.47">you can have this time slicing as well as multiple processors. On each CPU,</a> <a href="#t=163.44">you can now have different programs running. In some cases,</a> <a href="#t=167.34">the same program may also be resident on those different CPUs.</a>
</p>
<p>
 
 <a href="#t=171.87"><strong>02:51</strong></a>
 
 
 <a href="#t=171.87">In this diagram, programs 1, 4,</a> <a href="#t=174.21">and 5 are tied to a single CPU,</a> <a href="#t=177.63">but programs 2 and 3 are across the two CPUs. Part of the operating</a> <a href="#t=182.59">system’s responsibility is scheduling within the CPU and across the CPUs.</a>
</p>
<p>
 
 <a href="#t=189.01"><strong>03:09</strong></a>
 
 
 <a href="#t=189.01">Not all types of software can take advantage of concurrency equally.</a> <a href="#t=192.79">The type of concurrency you have can change</a> <a href="#t=195.52">what kinds of models you would use when creating a concurrent program.</a>
</p>
<p>
 
 <a href="#t=200.08"><strong>03:20</strong></a>
 
 
 <a href="#t=200.08">Trivial concurrency is that where the different parts of the program can be</a> <a href="#t=203.86">split apart without concerns for each other.</a> <a href="#t=207.49">This can usually be achieved when activities within the program are completely</a> <a href="#t=211.87">independent of each other. This is easiest</a> <a href="#t=214.69">if there’s no shared data between the different components.</a>
</p>
<p>
 
 <a href="#t=218.32"><strong>03:38</strong></a>
 
 
 <a href="#t=218.32">Consider a web server.</a> <a href="#t=220.03">You can have multiple clients talking to the web server at a time because each</a> <a href="#t=224.05">one of those clients don’t need to be able to talk to each other.</a>
</p>
<p>
 
 <a href="#t=227.29"><strong>03:47</strong></a>
 
 
 <a href="#t=227.29">There may be some contention at the disk level,</a> <a href="#t=229.45">but as you saw in the lesson on latency,</a> <a href="#t=231.4">a huge amount of processing can be done while a server’s waiting for the disk.</a>
</p>
<p>
 
 <a href="#t=236.35"><strong>03:56</strong></a>
 
 
 <a href="#t=236.35">In the non-trivial case,</a> <a href="#t=237.67">you have to share data across your concurrent components.</a> <a href="#t=241.15">When you’re thinking about this situation,</a> <a href="#t=243.04">it’s useful to think of three steps in processing: input, computing, and output.</a>
</p>
<p>
 
 <a href="#t=249.43"><strong>04:09</strong></a>
 
 
 <a href="#t=249.43">Concurrency is generally done by splitting up the compute portion,</a> <a href="#t=253.03">but that may mean that there’s coordination necessary for the input and output</a> <a href="#t=256.66">stages. You may also need coordination amongst the different compute nodes,</a> <a href="#t=261.67">depending on what kind of algorithm you’re running.</a>
</p>
<p>
 
 <a href="#t=265.75"><strong>04:25</strong></a>
 
 
 <a href="#t=265.75">Using the input, compute, and output model,</a> <a href="#t=268.06">you can think of programs in three parts.</a> <a href="#t=271.03">A producer is a component that produces data.</a> <a href="#t=274.36">This might mean reading something off the disk.</a>
</p>
<p>
 
 <a href="#t=277.33"><strong>04:37</strong></a>
 
 
 <a href="#t=277.33">The worker is the component that does the actual computation. And the consumer is</a> <a href="#t=282.94">the component that consumes the data or aggregates the output.</a> <a href="#t=287.77">Consider for a moment doing some image processing on a very large file.</a>
</p>
<p>
 
 <a href="#t=292.33"><strong>04:52</strong></a>
 
 
 <a href="#t=292.33">The producer portion of your program would read the large image format,</a> <a href="#t=296.86">the worker portion of your program would do the actual filtering on the image,</a> <a href="#t=301.84">and the consumer component would consume the result from the worker and write</a> <a href="#t=306.19">the new image to the hard drive. Depending on the architecture of your program,</a> <a href="#t=311.05">these concepts might be mixed and matched. Using these three ideas,</a> <a href="#t=316.03">you can introduce different patterns in concurrency.</a>
</p>
<p>
 
 <a href="#t=319.27"><strong>05:19</strong></a>
 
 
 <a href="#t=319.27">This simple pattern has a producer pushing data to a worker, which pushes data to</a> <a href="#t=324.73">a consumer.</a> <a href="#t=325.96">It might not be immediately evident where you can get concurrency here,</a> <a href="#t=329.89">but because producers and consumers are interacting with the disk,</a> <a href="#t=333.7">a lot of work can be done in the worker while producers and consumers are</a> <a href="#t=337.81">working independently. Thinking back to the image processing example,</a> <a href="#t=342.4">the producer might read thousands of bytes off the disk,</a> <a href="#t=345.61">hand them off to the worker.</a>
</p>
<p>
 
 <a href="#t=347.41"><strong>05:47</strong></a>
 
 
 <a href="#t=347.41">The worker could then manipulate those thousands of bytes, creating a result,</a> <a href="#t=351.85">which the consumer would then write to the disk. Unless the worker is</a> <a href="#t=355.9">particularly computationally intensive, in all likelihood it will</a> <a href="#t=360.32">most of the time be waiting for the producer and consumer.</a>
</p>
<p>
 
 <a href="#t=363.92"><strong>06:03</strong></a>
 
 
 <a href="#t=363.92">But as soon as the worker has been fed data, it can start working.</a> <a href="#t=367.49">The producer does not have to have read the entire image off of the disk.</a> <a href="#t=372.17">This can produce some concurrency.</a>
</p>
<p>
 
 <a href="#t=375.41"><strong>06:15</strong></a>
 
 
 <a href="#t=375.41">A variation on this pattern uses multiple workers.</a> <a href="#t=378.77">Your producer reads information off of the disk,</a> <a href="#t=381.5">hands it off to a worker, which begins computation.</a> <a href="#t=384.68">The producer then reads more information off to the disk and hands it off to a</a> <a href="#t=388.43">second or third worker. The workers work independently, creating a result,</a> <a href="#t=393.62">and then the consumer is responsible for writing it back to disk.</a>
</p>
<p>
 
 <a href="#t=397.61"><strong>06:37</strong></a>
 
 
 <a href="#t=397.61">This pattern is common with the processing of very large images.</a> <a href="#t=401.48">For the most part,</a> <a href="#t=402.62">an image can be broken up into components, and image processing can be done on</a> <a href="#t=406.64">those components independently.</a>
</p>
<p>
 
 <a href="#t=409.25"><strong>06:49</strong></a>
 
 
 <a href="#t=409.25">This means the workers don’t have to talk to each other very often, giving a high</a> <a href="#t=413.6">degree of parallelism between the work they’re performing.</a>
</p>
<p>
 
 <a href="#t=417.98"><strong>06:57</strong></a>
 
 
 <a href="#t=417.98">A variation on this pattern is for the producer to broadcast. In this case,</a> <a href="#t=422.27">each worker sees all of the data. It may not operate on all of the data,</a> <a href="#t=426.65">but as the data is exposed to it, it can continue to work.</a>
</p>
<p>
 
 <a href="#t=431.51"><strong>07:11</strong></a>
 
 
 <a href="#t=431.51">These patterns can also be mixed and matched.</a> <a href="#t=434.06">You can have your producers broadcasting to workers,</a> <a href="#t=436.79">workers talking to other workers,</a> <a href="#t=438.77">and those workers consolidating information for the consumer.</a>
</p>
<p>
 
 <a href="#t=443.78"><strong>07:23</strong></a>
 
 
 <a href="#t=443.78">Programming</a> <a href="#t=444.23">concurrent systems introduces all sorts of new challenges to your software.</a> <a href="#t=448.79">Some things to consider. You must make sure that you’ve got execution</a> <a href="#t=452.51">coordination—different processes have to be able to sync up with each other.</a>
</p>
<p>
 
 <a href="#t=456.74"><strong>07:36</strong></a>
 
 
 <a href="#t=456.74">Think of the image processing example.</a> <a href="#t=458.84">Let’s say your image was a megabyte large and split up into 10,000-kilobyte</a> <a href="#t=462.83">chunks. Each worker could work on one of those 10-kilobyte chunks,</a> <a href="#t=467.21">but in all likelihood,</a> <a href="#t=468.62">the borders between those 10-kilobyte chunks might impact the calculation in the</a> <a href="#t=473.75">chunk of image next door. So although for the most part</a> <a href="#t=477.41">the workers can work independently,</a> <a href="#t=479.45">when they reach the borders of the portions they’re working on,</a> <a href="#t=482.36">they may need to speak with other workers.</a>
</p>
<p>
 
 <a href="#t=485.93"><strong>08:05</strong></a>
 
 
 <a href="#t=485.93">Once you have multiple processes operating, the operating system or the</a> <a href="#t=489.65">programmer themselves has to determine how memory is allocated across those</a> <a href="#t=493.97">multiple processes. This is hard enough in a regular program,</a> <a href="#t=497.78">it just becomes more complicated when dealing with concurrency. Scheduling is</a> <a href="#t=502.28">about when to determine which processes are active.</a>
</p>
<p>
 
 <a href="#t=505.64"><strong>08:25</strong></a>
 
 
 <a href="#t=505.64">Thankfully, operating systems have done a lot of work on this. For the most part</a> <a href="#t=509.72">when you’re writing concurrent programs,</a> <a href="#t=511.4">you just let the operating system do the scheduling. But of course,</a> <a href="#t=514.88">that also means you’re giving up control,</a> <a href="#t=517.1">so there may be situations where this isn’t ideal.</a>
</p>
<p>
 
 <a href="#t=520.58"><strong>08:40</strong></a>
 
 
 <a href="#t=520.58">Typically, the reason you’re writing a concurrent application in the first place</a> <a href="#t=523.97">is to be able to get things done faster.</a> <a href="#t=526.82">And really what you’re talking about here is higher throughput—</a><a href="#t=530.18">more work done per unit time. How you manage execution coordination,</a> <a href="#t=534.98">memory allocation, and scheduling can change the throughput on your system,</a> <a href="#t=539.49">and you might need to fine-tune how these things behave in order to actually see</a> <a href="#t=543.68">speed-up. Somewhat related to scheduling is also distribution.</a>
</p>
<p>
 
 <a href="#t=548.37"><strong>09:08</strong></a>
 
 
 <a href="#t=548.37">How do you split up at the different concurrent pieces amongst the CPUs on your</a> <a href="#t=552.63">machine or between machines?</a> <a href="#t=555.02">Writing concurrent software introduces algorithmic challenges.</a>
</p>
<p>
 
 <a href="#t=559.65"><strong>09:19</strong></a>
 
 
 <a href="#t=559.65">Deadlocks are when two or more components are waiting on each other.</a> <a href="#t=563.7">If <em>A</em> is expecting <em>B</em> to do something, and <em>B</em> is waiting for <em>A</em> to do something,</a> <a href="#t=568.02">nothing is ever going to happen. And finally,</a> <a href="#t=571.23">resource starvation may also be a problem.</a>
</p>
<p>
 
 <a href="#t=573.81"><strong>09:33</strong></a>
 
 
 <a href="#t=573.81">The different components of your program may be fighting for memory, disk space,</a> <a href="#t=578.16">or access to the CPU.</a>
</p>
<p>
 
 <a href="#t=581.85"><strong>09:41</strong></a>
 
 
 <a href="#t=581.85">Concurrency can be applied at different levels in Python.</a> <a href="#t=585.21">The simplest is at the operating system level. This means, as a programmer,</a> <a href="#t=588.93">you don’t have to really worry about it.</a>
</p>
<p>
 
 <a href="#t=590.91"><strong>09:50</strong></a>
 
 
 <a href="#t=590.91">You can run Python in a window or in your IDE and let the operating system take</a> <a href="#t=595.47">care of the fact that other things are happening at the same time.</a> <a href="#t=599.25">If you have multiple processors available on your computer,</a> <a href="#t=602.16">you can use the multiprocessor library in Python to have code execute on those</a> <a href="#t=606.93">different processors.</a>
</p>
<p>
 
 <a href="#t=609.12"><strong>10:09</strong></a>
 
 
 <a href="#t=609.12">Modern operating systems have a lighter-weight way of getting concurrency called</a> <a href="#t=613.02">threads.</a> <a href="#t=614.04">Each thread in a program can execute different code. Threads can then be</a> <a href="#t=618.45">scheduled to take advantage of the I/O-bound nature of your program.</a>
</p>
<p>
 
 <a href="#t=622.98"><strong>10:22</strong></a>
 
 
 <a href="#t=622.98">In addition to having threads in the standard library,</a> <a href="#t=625.68">Python has another mechanism using coroutines called <code>asyncio</code>.</a> <a href="#t=630.48">The rest of this course describes the async I/O, thread, and multiprocessor</a> <a href="#t=635.22">standard libraries in Python and the differences between them. When considering</a> <a href="#t=640.65">concurrency inside of Python, you have to be aware of the GIL.</a>
</p>
<p>
 
 <a href="#t=644.52"><strong>10:44</strong></a>
 
 
 <a href="#t=644.52">This is the <em>Global Interpreter Lock</em>.</a> <a href="#t=647.43">The GIL is a thread lock, or mutex, that makes sure that only one thread</a> <a href="#t=652.05">controls the interpreter at a time.</a>
</p>
<p>
 
 <a href="#t=654.57"><strong>10:54</strong></a>
 
 
 <a href="#t=654.57">This limits the way multiple threads can operate inside of Python.</a> <a href="#t=660.0">When two concurrent parts of a program operate at the same time,</a> <a href="#t=663.57">you can get race conditions.</a>
</p>
<p>
 
 <a href="#t=665.58"><strong>11:05</strong></a>
 
 
 <a href="#t=665.58">If you have this kind of race condition inside of memory allocation,</a> <a href="#t=668.94">you will get memory leaks. The GIL was introduced to solve this problem.</a> <a href="#t=673.98">One of the powers of Python is the ability to extend it</a> <a href="#t=677.13">using C. You can write code in C and plug it in underneath</a> <a href="#t=681.81">and then have it called by Python. Although this makes Python powerful,</a> <a href="#t=686.04">it also makes memory allocation challenging.</a>
</p>
<p>
 
 <a href="#t=689.01"><strong>11:29</strong></a>
 
 
 <a href="#t=689.01">Now you have to deal with memory both at the interpreter level</a> <a href="#t=691.52">and at the C extension level.</a> <a href="#t=694.05">The GIL is particularly important when dealing with these kinds of</a> <a href="#t=697.98">interactions. If you do a quick Google on Python and GIL,</a> <a href="#t=702.48">you’ll find all sorts of opinions out there. It is seen by some</a> <a href="#t=706.44">as a limitation. Whatever you feel about it,</a> <a href="#t=709.23">it’s deeply nested inside of the interpreter, and removing it is not a simple</a> <a href="#t=713.44">thing.</a>
</p>
<p>
 
 <a href="#t=714.73"><strong>11:54</strong></a>
 
 
 <a href="#t=714.73">The original inventor of Python, a gentlemen named Guido, has stated that the GIL</a> <a href="#t=719.39">should only be removed</a> <a href="#t=720.67">if new code does not decrease the performance of a single-threaded program.</a>
</p>
<p>
 
 <a href="#t=725.38"><strong>12:05</strong></a>
 
 
 <a href="#t=725.38">This is one of the reasons it’s stuck around for such a long time. To be clear,</a> <a href="#t=730.09">the GIL is an implementation detail of the interpreter.</a> <a href="#t=733.3">CPython and PyPy both have it</a> <a href="#t=735.82">but Jython and IronPython do not use the GIL,</a> <a href="#t=739.42">so depending on your underlying interpreter, you may or may not run into this.</a>
</p>
<p>
 
 <a href="#t=745.45"><strong>12:25</strong></a>
 
 
 <a href="#t=745.45">This course was recorded in the fall of 2020.</a> <a href="#t=748.63">At the time of recording, PEP 554</a> <a href="#t=750.85">was being worked on. This PEP introduces Multiple Interpreters in the</a> <a href="#t=755.59">Stdlib. This concept is something called <em>subinterpreters</em>.</a>
</p>
<p>
 
 <a href="#t=760.05"><strong>12:40</strong></a>
 
 
 <a href="#t=760.05">CPython already has this idea and it allows C extensions to kick off multiple</a> <a href="#t=765.46">Python interpreters at a time. Each subinterpreter has its own GIL,</a> <a href="#t=770.5">and so C extension level code is able to get concurrency without the</a> <a href="#t=774.76">challenges of the GIL involved.</a>
</p>
<p>
 
 <a href="#t=777.82"><strong>12:57</strong></a>
 
 
 <a href="#t=777.82">The interpreters are essentially independent of each other. PEP 554</a> <a href="#t=782.4">proposes exposing these interpreters in the Python standard library.</a> <a href="#t=787.3">This doesn’t fix the GIL,</a> <a href="#t=788.95">but would give programmers access to more tools that allow them to work around</a> <a href="#t=793.39">the GIL. And as changes happen around the GIL,</a> <a href="#t=796.6">they could be exposed to the programmers earlier inside of these</a> <a href="#t=799.39">subinterpreters, hopefully improving the ability to do concurrency in Python.</a>
</p>
<p>
 
 <a href="#t=805.96"><strong>13:25</strong></a>
 
 
 <a href="#t=805.96">Although the GIL is a challenge,</a> <a href="#t=807.52">the I/O-bound nature of most programs means that you can still do concurrency in</a> <a href="#t=811.78">Python. In the next lesson, I’ll introduce you to the <code>threading</code> library,</a> <a href="#t=815.86">a good way to do just that.</a>
</p>
 </div>||||I|||| * Start Here
 * Learn Python
 Python Tutorials →
 In-depth articles and video courses Learning Paths →
 Guided study plans for accelerated learning Quizzes →
 Check your learning progress Browse Topics →
 Focus on a specific area or skill level Community Chat →
 Learn with other Pythonistas Office Hours →
 Live Q&A calls with Python experts Podcast →
 Hear what’s new in the world of Python Books →
 Round out your knowledge and learn offline Unlock All Content →
 * More
 Python Learning Resources Python Newsletter Python Job Board Meet the Team Become a Tutorial Writer Become a Video Instructor
 * Search
 * Join
 * Sign‑In

 ⛄️ Winter Warm-Up Giveaway: Enter for a chance to win prizes worth over $1,210 »

 Exit Fullscreen
 Hint: You can adjust the default video playback speed in your account settings. ×
 Hint: You can set the default subtitles language in your account settings. ×
 Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue. ×

 Concurrency

 Speed Up Python With Concurrency
 Christopher Trudeau 13:39

 Mark as Completed
 Supporting Material
 Recommended Tutorial Course Slides (.pdf) Sample Code (.zip)
 * Transcript
 * Discussion (1)

 00:00 In the previous lesson, I talked about the degrees of latency in the different components of your computer. In this lesson, I’m going to show you how that’s taken advantage of to create concurrency.

 00:11 Recall this diagram from the previous lesson. It’s common for a program to have to wait long periods of time for it to be able to do the next instruction.

 00:21 It needs to wait on RAM, disk, and network. Time slicing is the idea of the operating system mixing other programs into these wait states. While you’re waiting for that network packet to come back from Prague, the computer can insert multiple other programs to take advantage of that time.

 00:40 This time slicing is how a single processor computer can look like it’s doing multiple things at the same time.

 00:48 Time slicing for multitasking can be thought of at three levels. The lowest level is not having any at all. The olden days of personal computers, the DOS operating system worked this way.

 00:59 You could only run a single program at a time. Cooperative multitasking is when the program willingly gives up the CPU. If you know that you’re about to go out to the network and you’re not going to need the CPU for a while, you signal the operating system and the operating system can schedule a different program. In home computing, Windows 3.1 introduced this kind of multitasking.

 01:21 If you happen to be old enough to remember using this operating system, you may recall that at certain times the program would just stop refreshing. That would be because it didn’t give up the CPU, but it was stuck in a wait state, so the UI was not being updated because the program had not told the operating system to put it into the wait state. As the name implies, cooperative multitasking requires all of the processes to cooperate with each other. In shared computing, or in the case of a program with a problem, this can be a challenge.

 01:54 So preemptive multitasking was created. The operating system, in this case, interrupts the program whether or not it’s ready. The operating system is responsible for swapping between the different programs.

 02:07 In most operating systems, this is done intelligently. If your program does do a network call, that triggers the operating system to take advantage of it and put the program into a wait state.

 02:18 But it can also do it in the case where the program is being a hog and hasn’t given up the CPU.

 02:24 Mainframes have done this from very early on, as has Unix. In the Windows world, NT and Windows 95 is where preemptive multitasking was first introduced.

 02:36 On larger computers, you can have this time slicing as well as multiple processors. On each CPU, you can now have different programs running. In some cases, the same program may also be resident on those different CPUs.

 02:51 In this diagram, programs 1, 4, and 5 are tied to a single CPU, but programs 2 and 3 are across the two CPUs. Part of the operating system’s responsibility is scheduling within the CPU and across the CPUs.

 03:09 Not all types of software can take advantage of concurrency equally. The type of concurrency you have can change what kinds of models you would use when creating a concurrent program.

 03:20 Trivial concurrency is that where the different parts of the program can be split apart without concerns for each other. This can usually be achieved when activities within the program are completely independent of each other. This is easiest if there’s no shared data between the different components.

 03:38 Consider a web server. You can have multiple clients talking to the web server at a time because each one of those clients don’t need to be able to talk to each other.

 03:47 There may be some contention at the disk level, but as you saw in the lesson on latency, a huge amount of processing can be done while a server’s waiting for the disk.

 03:56 In the non-trivial case, you have to share data across your concurrent components. When you’re thinking about this situation, it’s useful to think of three steps in processing: input, computing, and output.

 04:09 Concurrency is generally done by splitting up the compute portion, but that may mean that there’s coordination necessary for the input and output stages. You may also need coordination amongst the different compute nodes, depending on what kind of algorithm you’re running.

 04:25 Using the input, compute, and output model, you can think of programs in three parts. A producer is a component that produces data. This might mean reading something off the disk.

 04:37 The worker is the component that does the actual computation. And the consumer is the component that consumes the data or aggregates the output. Consider for a moment doing some image processing on a very large file.

 04:52 The producer portion of your program would read the large image format, the worker portion of your program would do the actual filtering on the image, and the consumer component would consume the result from the worker and write the new image to the hard drive. Depending on the architecture of your program, these concepts might be mixed and matched. Using these three ideas, you can introduce different patterns in concurrency.

 05:19 This simple pattern has a producer pushing data to a worker, which pushes data to a consumer. It might not be immediately evident where you can get concurrency here, but because producers and consumers are interacting with the disk, a lot of work can be done in the worker while producers and consumers are working independently. Thinking back to the image processing example, the producer might read thousands of bytes off the disk, hand them off to the worker.

 05:47 The worker could then manipulate those thousands of bytes, creating a result, which the consumer would then write to the disk. Unless the worker is particularly computationally intensive, in all likelihood it will most of the time be waiting for the producer and consumer.

 06:03 But as soon as the worker has been fed data, it can start working. The producer does not have to have read the entire image off of the disk. This can produce some concurrency.

 06:15 A variation on this pattern uses multiple workers. Your producer reads information off of the disk, hands it off to a worker, which begins computation. The producer then reads more information off to the disk and hands it off to a second or third worker. The workers work independently, creating a result, and then the consumer is responsible for writing it back to disk.

 06:37 This pattern is common with the processing of very large images. For the most part, an image can be broken up into components, and image processing can be done on those components independently.

 06:49 This means the workers don’t have to talk to each other very often, giving a high degree of parallelism between the work they’re performing.

 06:57 A variation on this pattern is for the producer to broadcast. In this case, each worker sees all of the data. It may not operate on all of the data, but as the data is exposed to it, it can continue to work.

 07:11 These patterns can also be mixed and matched. You can have your producers broadcasting to workers, workers talking to other workers, and those workers consolidating information for the consumer.

 07:23 Programming concurrent systems introduces all sorts of new challenges to your software. Some things to consider. You must make sure that you’ve got execution coordination—different processes have to be able to sync up with each other.

 07:36 Think of the image processing example. Let’s say your image was a megabyte large and split up into 10,000-kilobyte chunks. Each worker could work on one of those 10-kilobyte chunks, but in all likelihood, the borders between those 10-kilobyte chunks might impact the calculation in the chunk of image next door. So although for the most part the workers can work independently, when they reach the borders of the portions they’re working on, they may need to speak with other workers.

 08:05 Once you have multiple processes operating, the operating system or the programmer themselves has to determine how memory is allocated across those multiple processes. This is hard enough in a regular program, it just becomes more complicated when dealing with concurrency. Scheduling is about when to determine which processes are active.

 08:25 Thankfully, operating systems have done a lot of work on this. For the most part when you’re writing concurrent programs, you just let the operating system do the scheduling. But of course, that also means you’re giving up control, so there may be situations where this isn’t ideal.

 08:40 Typically, the reason you’re writing a concurrent application in the first place is to be able to get things done faster. And really what you’re talking about here is higher throughput—more work done per unit time. How you manage execution coordination, memory allocation, and scheduling can change the throughput on your system, and you might need to fine-tune how these things behave in order to actually see speed-up. Somewhat related to scheduling is also distribution.

 09:08 How do you split up at the different concurrent pieces amongst the CPUs on your machine or between machines? Writing concurrent software introduces algorithmic challenges.

 09:19 Deadlocks are when two or more components are waiting on each other. If A is expecting B to do something, and B is waiting for A to do something, nothing is ever going to happen. And finally, resource starvation may also be a problem.

 09:33 The different components of your program may be fighting for memory, disk space, or access to the CPU.

 09:41 Concurrency can be applied at different levels in Python. The simplest is at the operating system level. This means, as a programmer, you don’t have to really worry about it.

 09:50 You can run Python in a window or in your IDE and let the operating system take care of the fact that other things are happening at the same time. If you have multiple processors available on your computer, you can use the multiprocessor library in Python to have code execute on those different processors.

 10:09 Modern operating systems have a lighter-weight way of getting concurrency called threads. Each thread in a program can execute different code. Threads can then be scheduled to take advantage of the I/O-bound nature of your program.

 10:22 In addition to having threads in the standard library, Python has another mechanism using coroutines called asyncio. The rest of this course describes the async I/O, thread, and multiprocessor standard libraries in Python and the differences between them. When considering concurrency inside of Python, you have to be aware of the GIL.

 10:44 This is the Global Interpreter Lock. The GIL is a thread lock, or mutex, that makes sure that only one thread controls the interpreter at a time.

 10:54 This limits the way multiple threads can operate inside of Python. When two concurrent parts of a program operate at the same time, you can get race conditions.

 11:05 If you have this kind of race condition inside of memory allocation, you will get memory leaks. The GIL was introduced to solve this problem. One of the powers of Python is the ability to extend it using C. You can write code in C and plug it in underneath and then have it called by Python. Although this makes Python powerful, it also makes memory allocation challenging.

 11:29 Now you have to deal with memory both at the interpreter level and at the C extension level. The GIL is particularly important when dealing with these kinds of interactions. If you do a quick Google on Python and GIL, you’ll find all sorts of opinions out there. It is seen by some as a limitation. Whatever you feel about it, it’s deeply nested inside of the interpreter, and removing it is not a simple thing.

 11:54 The original inventor of Python, a gentlemen named Guido, has stated that the GIL should only be removed if new code does not decrease the performance of a single-threaded program.

 12:05 This is one of the reasons it’s stuck around for such a long time. To be clear, the GIL is an implementation detail of the interpreter. CPython and PyPy both have it but Jython and IronPython do not use the GIL, so depending on your underlying interpreter, you may or may not run into this.

 12:25 This course was recorded in the fall of 2020. At the time of recording, PEP 554 was being worked on. This PEP introduces Multiple Interpreters in the Stdlib. This concept is something called subinterpreters.

 12:40 CPython already has this idea and it allows C extensions to kick off multiple Python interpreters at a time. Each subinterpreter has its own GIL, and so C extension level code is able to get concurrency without the challenges of the GIL involved.

 12:57 The interpreters are essentially independent of each other. PEP 554 proposes exposing these interpreters in the Python standard library. This doesn’t fix the GIL, but would give programmers access to more tools that allow them to work around the GIL. And as changes happen around the GIL, they could be exposed to the programmers earlier inside of these subinterpreters, hopefully improving the ability to do concurrency in Python.

 13:25 Although the GIL is a challenge, the I/O-bound nature of most programs means that you can still do concurrency in Python. In the next lesson, I’ll introduce you to the threading library, a good way to do just that.

 ldr3tlogy on Dec. 10, 2020

 Excellent summary, easy to follow the producer, worker, consumer analogy, and various combinations of each, architecting different concurrent algorithms, thereby improving throughput.

 Become a Member to join the conversation.

 Course Contents

 Overview
 33%
 * Speed Up Python With Concurrency (Overview) 03:02
 * Computers and Latency 07:40
 * Concurrency 13:39
 * Threads in Python 11:08
 * Race Conditions 07:01
 * asyncio Version 09:50
 * Multi-Processing Version 06:44
 * CPU Bound Workloads 07:47
 * Speed Up Python With Concurrency (Summary) 05:46

 © 2012–2023 Real Python ⋅ Privacy Policy

00:00 
 
 
 In the previous lesson, I talked about the degrees of latency in the different components of your computer. In this lesson, I’m going to show you how that’s taken advantage of to create concurrency.
 
  00:11 
 
 
 Recall this diagram from the previous lesson. It’s common for a program to have to wait long periods of time for it to be able to do the next instruction.
 
  00:21 
 
 
 It needs to wait on RAM, disk, and network. Time slicing is the idea of the operating system mixing other programs into these wait states. While you’re waiting for that network packet to come back from Prague, the computer can insert multiple other programs to take advantage of that time.
 
  00:40 
 
 
 This time slicing is how a single processor computer can look like it’s doing multiple things at the same time.
 
  00:48 
 
 
 Time slicing for multitasking can be thought of at three levels. The lowest level is not having any at all. The olden days of personal computers, the DOS operating system worked this way.
 
  00:59 
 
 
 You could only run a single program at a time. Cooperative multitasking is when the program willingly gives up the CPU. If you know that you’re about to go out to the network and you’re not going to need the CPU for a while, you signal the operating system and the operating system can schedule a different program. In home computing, Windows 3.1 introduced this kind of multitasking.
 
  01:21 
 
 
 If you happen to be old enough to remember using this operating system, you may recall that at certain times the program would just stop refreshing. That would be because it didn’t give up the CPU, but it was stuck in a wait state, so the UI was not being updated because the program had not told the operating system to put it into the wait state. As the name implies, cooperative multitasking requires all of the processes to cooperate with each other. In shared computing, or in the case of a program with a problem, this can be a challenge.
 
  01:54 
 
 
 So preemptive multitasking was created. The operating system, in this case, interrupts the program whether or not it’s ready. The operating system is responsible for swapping between the different programs.
 
  02:07 
 
 
 In most operating systems, this is done intelligently. If your program does do a network call, that triggers the operating system to take advantage of it and put the program into a wait state.
 
  02:18 
 
 
 But it can also do it in the case where the program is being a hog and hasn’t given up the CPU.
 
  02:24 
 
 
 Mainframes have done this from very early on, as has Unix. In the Windows world, NT and Windows 95 is where preemptive multitasking was first introduced.
 
  02:36 
 
 
 On larger computers, you can have this time slicing as well as multiple processors. On each CPU, you can now have different programs running. In some cases, the same program may also be resident on those different CPUs.
 
  02:51 
 
 
 In this diagram, programs 1, 4, and 5 are tied to a single CPU, but programs 2 and 3 are across the two CPUs. Part of the operating system’s responsibility is scheduling within the CPU and across the CPUs.
 
  03:09 
 
 
 Not all types of software can take advantage of concurrency equally. The type of concurrency you have can change what kinds of models you would use when creating a concurrent program.
 
  03:20 
 
 
 Trivial concurrency is that where the different parts of the program can be split apart without concerns for each other. This can usually be achieved when activities within the program are completely independent of each other. This is easiest if there’s no shared data between the different components.
 
  03:38 
 
 
 Consider a web server. You can have multiple clients talking to the web server at a time because each one of those clients don’t need to be able to talk to each other.
 
  03:47 
 
 
 There may be some contention at the disk level, but as you saw in the lesson on latency, a huge amount of processing can be done while a server’s waiting for the disk.
 
  03:56 
 
 
 In the non-trivial case, you have to share data across your concurrent components. When you’re thinking about this situation, it’s useful to think of three steps in processing: input, computing, and output.
 
  04:09 
 
 
 Concurrency is generally done by splitting up the compute portion, but that may mean that there’s coordination necessary for the input and output stages. You may also need coordination amongst the different compute nodes, depending on what kind of algorithm you’re running.
 
  04:25 
 
 
 Using the input, compute, and output model, you can think of programs in three parts. A producer is a component that produces data. This might mean reading something off the disk.
 
  04:37 
 
 
 The worker is the component that does the actual computation. And the consumer is the component that consumes the data or aggregates the output. Consider for a moment doing some image processing on a very large file.
 
  04:52 
 
 
 The producer portion of your program would read the large image format, the worker portion of your program would do the actual filtering on the image, and the consumer component would consume the result from the worker and write the new image to the hard drive. Depending on the architecture of your program, these concepts might be mixed and matched. Using these three ideas, you can introduce different patterns in concurrency.
 
  05:19 
 
 
 This simple pattern has a producer pushing data to a worker, which pushes data to a consumer. It might not be immediately evident where you can get concurrency here, but because producers and consumers are interacting with the disk, a lot of work can be done in the worker while producers and consumers are working independently. Thinking back to the image processing example, the producer might read thousands of bytes off the disk, hand them off to the worker.
 
  05:47 
 
 
 The worker could then manipulate those thousands of bytes, creating a result, which the consumer would then write to the disk. Unless the worker is particularly computationally intensive, in all likelihood it will most of the time be waiting for the producer and consumer.
 
  06:03 
 
 
 But as soon as the worker has been fed data, it can start working. The producer does not have to have read the entire image off of the disk. This can produce some concurrency.
 
  06:15 
 
 
 A variation on this pattern uses multiple workers. Your producer reads information off of the disk, hands it off to a worker, which begins computation. The producer then reads more information off to the disk and hands it off to a second or third worker. The workers work independently, creating a result, and then the consumer is responsible for writing it back to disk.
 
  06:37 
 
 
 This pattern is common with the processing of very large images. For the most part, an image can be broken up into components, and image processing can be done on those components independently.
 
  06:49 
 
 
 This means the workers don’t have to talk to each other very often, giving a high degree of parallelism between the work they’re performing.
 
  06:57 
 
 
 A variation on this pattern is for the producer to broadcast. In this case, each worker sees all of the data. It may not operate on all of the data, but as the data is exposed to it, it can continue to work.
 
  07:11 
 
 
 These patterns can also be mixed and matched. You can have your producers broadcasting to workers, workers talking to other workers, and those workers consolidating information for the consumer.
 
  07:23 
 
 
 Programming concurrent systems introduces all sorts of new challenges to your software. Some things to consider. You must make sure that you’ve got execution coordination—different processes have to be able to sync up with each other.
 
  07:36 
 
 
 Think of the image processing example. Let’s say your image was a megabyte large and split up into 10,000-kilobyte chunks. Each worker could work on one of those 10-kilobyte chunks, but in all likelihood, the borders between those 10-kilobyte chunks might impact the calculation in the chunk of image next door. So although for the most part the workers can work independently, when they reach the borders of the portions they’re working on, they may need to speak with other workers.
 
  08:05 
 
 
 Once you have multiple processes operating, the operating system or the programmer themselves has to determine how memory is allocated across those multiple processes. This is hard enough in a regular program, it just becomes more complicated when dealing with concurrency. Scheduling is about when to determine which processes are active.
 
  08:25 
 
 
 Thankfully, operating systems have done a lot of work on this. For the most part when you’re writing concurrent programs, you just let the operating system do the scheduling. But of course, that also means you’re giving up control, so there may be situations where this isn’t ideal.
 
  08:40 
 
 
 Typically, the reason you’re writing a concurrent application in the first place is to be able to get things done faster. And really what you’re talking about here is higher throughput— more work done per unit time. How you manage execution coordination, memory allocation, and scheduling can change the throughput on your system, and you might need to fine-tune how these things behave in order to actually see speed-up. Somewhat related to scheduling is also distribution.
 
  09:08 
 
 
 How do you split up at the different concurrent pieces amongst the CPUs on your machine or between machines? Writing concurrent software introduces algorithmic challenges.
 
  09:19 
 
 
 Deadlocks are when two or more components are waiting on each other. If A is expecting B to do something, and B is waiting for A to do something, nothing is ever going to happen. And finally, resource starvation may also be a problem.
 
  09:33 
 
 
 The different components of your program may be fighting for memory, disk space, or access to the CPU.
 
  09:41 
 
 
 Concurrency can be applied at different levels in Python. The simplest is at the operating system level. This means, as a programmer, you don’t have to really worry about it.
 
  09:50 
 
 
 You can run Python in a window or in your IDE and let the operating system take care of the fact that other things are happening at the same time. If you have multiple processors available on your computer, you can use the multiprocessor library in Python to have code execute on those different processors.
 
  10:09 
 
 
 Modern operating systems have a lighter-weight way of getting concurrency called threads. Each thread in a program can execute different code. Threads can then be scheduled to take advantage of the I/O-bound nature of your program.
 
  10:22 
 
 
 In addition to having threads in the standard library, Python has another mechanism using coroutines called asyncio. The rest of this course describes the async I/O, thread, and multiprocessor standard libraries in Python and the differences between them. When considering concurrency inside of Python, you have to be aware of the GIL.
 
  10:44 
 
 
 This is the Global Interpreter Lock. The GIL is a thread lock, or mutex, that makes sure that only one thread controls the interpreter at a time.
 
  10:54 
 
 
 This limits the way multiple threads can operate inside of Python. When two concurrent parts of a program operate at the same time, you can get race conditions.
 
  11:05 
 
 
 If you have this kind of race condition inside of memory allocation, you will get memory leaks. The GIL was introduced to solve this problem. One of the powers of Python is the ability to extend it using C. You can write code in C and plug it in underneath and then have it called by Python. Although this makes Python powerful, it also makes memory allocation challenging.
 
  11:29 
 
 
 Now you have to deal with memory both at the interpreter level and at the C extension level. The GIL is particularly important when dealing with these kinds of interactions. If you do a quick Google on Python and GIL, you’ll find all sorts of opinions out there. It is seen by some as a limitation. Whatever you feel about it, it’s deeply nested inside of the interpreter, and removing it is not a simple thing.
 
  11:54 
 
 
 The original inventor of Python, a gentlemen named Guido, has stated that the GIL should only be removed if new code does not decrease the performance of a single-threaded program.
 
  12:05 
 
 
 This is one of the reasons it’s stuck around for such a long time. To be clear, the GIL is an implementation detail of the interpreter. CPython and PyPy both have it but Jython and IronPython do not use the GIL, so depending on your underlying interpreter, you may or may not run into this.
 
  12:25 
 
 
 This course was recorded in the fall of 2020. At the time of recording, PEP 554 was being worked on. This PEP introduces Multiple Interpreters in the Stdlib. This concept is something called subinterpreters.
 
  12:40 
 
 
 CPython already has this idea and it allows C extensions to kick off multiple Python interpreters at a time. Each subinterpreter has its own GIL, and so C extension level code is able to get concurrency without the challenges of the GIL involved.
 
  12:57 
 
 
 The interpreters are essentially independent of each other. PEP 554 proposes exposing these interpreters in the Python standard library. This doesn’t fix the GIL, but would give programmers access to more tools that allow them to work around the GIL. And as changes happen around the GIL, they could be exposed to the programmers earlier inside of these subinterpreters, hopefully improving the ability to do concurrency in Python.
 
  13:25 
 
 
 Although the GIL is a challenge, the I/O-bound nature of most programs means that you can still do concurrency in Python. In the next lesson, I’ll introduce you to the threading library, a good way to do just that.
Concurrency – Real Python
https://realpython.com/lessons/concurrency/
<div><div>
                                        
                                                                                    <p><span>Last Updated : </span>
                                                <span>15 Sep, 2023</span>
                                            </p>
                                                                            </div><div>
                                                                <p>This article is a brief yet concise introduction to <strong>multiprocessing</strong> in Python programming language.</p>
<p><strong>What is multiprocessing?</strong></p>
<p>Multiprocessing refers to the ability of a system to support more than one processor at the same time. Applications in a multiprocessing system are broken to smaller routines that run independently. The operating system allocates these threads to the processors improving performance of the system.</p>
<p><strong>Why multiprocessing?</strong></p>
<p>Consider a computer system with a single processor. If it is assigned several processes at the same time, it will have to interrupt each task and switch briefly to another, to keep all of the processes going.<br/>
This situation is just like a chef working in a kitchen alone. He has to do several tasks like baking, stirring, kneading dough, etc.</p>
<p>So the gist is that: The more tasks you must do at once, the more difficult it gets to keep track of them all, and keeping the timing right becomes more of a challenge.<br/>
This is where the concept of multiprocessing arises!<br/>
<strong>A multiprocessing system can have:</strong></p>
<ul>
<li>multiprocessor, i.e. a computer with more than one central processor.</li>
<li>multi-core processor, i.e. a single computing component with two or more independent actual processing units (called “cores”).</li>
</ul>
<p>Here, the CPU can easily executes several tasks at once, with each task using its own processor.</p>
<p>It is just like the chef in last situation being assisted by his assistants. Now, they can divide the tasks among themselves and chef doesn’t need to switch between his tasks.</p>
<p><strong>Multiprocessing in Python</strong></p>
<p>In Python, the <a href="https://docs.python.org/3/library/multiprocessing.html"><strong>multiprocessing</strong></a> module includes a very simple and intuitive API for dividing work between multiple processes.<br/>
Let us consider a simple example using multiprocessing module:</p>
<div>

<p><code>import</code> <code>multiprocessing </code></p>

<p><code>def</code> <code>print_cube(num): </code></p>



<p><code>    </code><code>print</code><code>(</code><code>"Cube: {}"</code><code>.</code><code>format</code><code>(num </code><code>*</code> <code>num </code><code>*</code> <code>num)) </code></p>

<p><code>def</code> <code>print_square(num): </code></p>



<p><code>    </code><code>print</code><code>(</code><code>"Square: {}"</code><code>.</code><code>format</code><code>(num </code><code>*</code> <code>num)) </code></p>

<p><code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>"__main__"</code><code>: </code></p>

<p><code>    </code><code>p1 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>print_square, args</code><code>=</code><code>(</code><code>10</code><code>, )) </code></p>
<p><code>    </code><code>p2 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>print_cube, args</code><code>=</code><code>(</code><code>10</code><code>, )) </code></p>


<p><code>    </code><code>p1.start() </code></p>

<p><code>    </code><code>p2.start() </code></p>


<p><code>    </code><code>p1.join() </code></p>

<p><code>    </code><code>p2.join() </code></p>


<p><code>    </code><code>print</code><code>(</code><code>"Done!"</code><code>) </code></p>
</div>

<pre>Square: 100
Cube: 1000
Done!
</pre>
<p>Let us try to understand the above code:</p>
<ul>
<li>To import the multiprocessing module, we do:
<pre>import multiprocessing
</pre>
</li>
<li>To create a process, we create an object of <strong>Process</strong> class. It takes following arguments:
<ul>
<li><strong>target</strong>: the function to be executed by process</li>
<li><strong>args</strong>: the arguments to be passed to the target function</li>
</ul>
<p>Note: <strong>Process</strong> constructor takes many other arguments also which will be discussed later. In above example, we created 2 processes with different target functions:</p>
<pre>p1 = multiprocessing.Process(target=print_square, args=(10, ))
p2 = multiprocessing.Process(target=print_cube, args=(10, ))
</pre>
</li>
<li>To start a process, we use <strong>start</strong> method of <strong>Process</strong> class.
<pre>p1.start()
p2.start()
</pre>
</li>
<li>Once the processes start, the current program also keeps on executing. In order to stop execution of current program until a process is complete, we use <strong>join</strong> method.
<pre>p1.join()
p2.join()
</pre>
<p>As a result, the current program will first wait for the completion of <strong>p1</strong> and then <strong>p2</strong>. Once, they are completed, the next statements of current program are executed.</p></li>
</ul>
<p>Let us consider another program to understand the concept of different processes running on same python script. In this example below, we print the ID of the processes running the target functions:</p>
<div>

<p><code>import</code> <code>multiprocessing </code></p>
<p><code>import</code> <code>os </code></p>

<p><code>def</code> <code>worker1(): </code></p>

<p><code>    </code><code>print</code><code>(</code><code>"ID of process running worker1: {}"</code><code>.</code><code>format</code><code>(os.getpid())) </code></p>

<p><code>def</code> <code>worker2(): </code></p>

<p><code>    </code><code>print</code><code>(</code><code>"ID of process running worker2: {}"</code><code>.</code><code>format</code><code>(os.getpid())) </code></p>

<p><code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>"__main__"</code><code>: </code></p>

<p><code>    </code><code>print</code><code>(</code><code>"ID of main process: {}"</code><code>.</code><code>format</code><code>(os.getpid())) </code></p>


<p><code>    </code><code>p1 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>worker1) </code></p>
<p><code>    </code><code>p2 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>worker2) </code></p>


<p><code>    </code><code>p1.start() </code></p>
<p><code>    </code><code>p2.start() </code></p>


<p><code>    </code><code>print</code><code>(</code><code>"ID of process p1: {}"</code><code>.</code><code>format</code><code>(p1.pid)) </code></p>
<p><code>    </code><code>print</code><code>(</code><code>"ID of process p2: {}"</code><code>.</code><code>format</code><code>(p2.pid)) </code></p>


<p><code>    </code><code>p1.join() </code></p>
<p><code>    </code><code>p2.join() </code></p>


<p><code>    </code><code>print</code><code>(</code><code>"Both processes finished execution!"</code><code>) </code></p>


<p><code>    </code><code>print</code><code>(</code><code>"Process p1 is alive: {}"</code><code>.</code><code>format</code><code>(p1.is_alive())) </code></p>
<p><code>    </code><code>print</code><code>(</code><code>"Process p2 is alive: {}"</code><code>.</code><code>format</code><code>(p2.is_alive())) </code></p>
</div>

<pre>ID of main process: 28628
ID of process running worker1: 29305
ID of process running worker2: 29306
ID of process p1: 29305
ID of process p2: 29306
Both processes finished execution!
Process p1 is alive: False
Process p2 is alive: False
</pre>
<ul>
<li>The main python script has a different process ID and multiprocessing module spawns new processes with different process IDs as we create <strong>Process</strong> objects <strong>p1</strong> and <strong>p2</strong>. In above program, we use <strong>os.getpid()</strong> function to get ID of process running the current target function.
<p>Notice that it matches with the process IDs of <strong>p1</strong> and <strong>p2</strong> which we obtain using <strong>pid</strong> attribute of <strong>Process</strong> class.</p></li>
<li> Each process runs independently and has its own memory space. </li>
<li>As soon as the execution of target function is finished, the processes get terminated. In above program we used <strong>is_alive</strong> method of <strong>Process</strong> class to check if a process is still active or not.</li>
</ul>
<p>Consider the diagram below to understand how new processes are different from main Python script:<br/>
<br/>
So, this was a brief introduction to multiprocessing in Python. Next few articles will cover following topics related to multiprocessing:</p>
<ul>
<li>Sharing data between processes using Array, value and queues.</li>
<li>Lock and Pool concepts in multiprocessing</li>
</ul>
<p><strong>Next:</strong></p>
<ul>
<li><a href="https://www.geeksforgeeks.org/multiprocessing-python-set-2/">Multiprocessing in Python | Set 2</a> </li>
<li><a href="https://www.geeksforgeeks.org/synchronization-pooling-processes-python/">Synchronization and Pooling of processes in Python</a></li>
</ul>
<p><strong>References:</strong></p>
<ul>
<li><a href="http://learn.parallax.com/tutorials/language/blocklyprop/blocklyprop-functions-and-multicore/bit-about-multicore">http://learn.parallax.com/tutorials/language/blocklyprop/blocklyprop-functions-and-multicore/bit-about-multicore</a></li>
<li><a href="https://docs.python.org/3/library/multiprocessing.html">https://docs.python.org/3/library/multiprocessing.html</a></li>
</ul>
<br/>

                                    <br/>
                                                                        


                            
                            <div>    <p> </p><h3>Please <u><span>Login</span></u> to comment...</h3><p></p>
                            

                            
</div>  
                        </div></div>||||I||||  Skip to content
      * Tutorials
          + Python Tutorial
              o Taking Input in Python
              o Python Operators
              o Python Data Types
                  - Python Numbers
                  - Python String
                  - Python Lists
                  - Python Tuples
                  - Sets in Python
                  - Python Dictionary
              o Python Loops and Control Flow
                  - Python Conditional Statements
                  - Python Loops
              o Python Functions
              o Python OOPS Concept
              o Python Data Structures
                  - Python DSA
                  - Linked List
                  - Stack
                  - Queue
                  - Tree
                  - Heap
                  - Hashing
                  - Graph
                  - Sets
                  - Map
                  - Advance Data Structure
                  - Sorting Algorithms
                  - Searching Algorithms
              o Python Exception Handling
              o Python File Handling
              o Python Exercises
                  - Python List Exercise
                  - Python String Exercise
                  - Python Tuple Exercise
                  - Python Dictionary Exercise
                  - Python Set Exercise
                  - Python Design Patterns
                  - Python Programming Examples
                  - Python Practice Questions
          + Java
              o Java Programming Language
                  - Java Tutorial
                  - Data Types
                  - Variables
                  - Operators
                  - Flow Control in Java
                  - Loops in Java
                  - Methods
                  - Strings
                  - Arrays
                  - OOPs Concepts
                      * OOPs Concepts
                      * Classes and Objects
                      * Access Modifiers
                      * Inheritance
                      * Abstraction
                      * Encapsulation
                      * Polymorphism
                  - Interface
                  - Packages
                  - Multithreading
                  - File Handling
                  - Regular Expression
              o Java Collections
                  - Java Collections
                  - Collection Class
                  - List Interface
                  - ArrayList
                  - LinkedList Class
                  - Queue Interface
                  - Set Interface
                  - HashSet Class
                  - Map Interface
                  - HashMap Class
                  - HashTable Class
                  - Iterator
                  - Comparator
                  - Collection Interview Questions
              o Java 8 Tutorial
              o Java Programs
                  - Java Programming Examples
                  - Java Array Programs
                  - Java String Programs
                  - Java Date-Time Programs
                  - Java File Handling Programs
                  - Java Collection Programs
                  - Java JDBC Programs
                  - Java Apache POI Programs
                  - Java OpenCV Programs
              o Java Interview Questions
                  - Java Interview Questions
                  - Core Java Interview Questions-Freshers
                  - Java Multithreading Interview Questions
                  - OOPs Interview Questions and Answers
              o Java Exercises
              o Java Quiz
                  - Java Quiz
                  - Core Java MCQ
              o Java Projects
              o Advance Java
                  - Spring Tutorial
                  - Spring Boot Tutorial
                  - Spring Boot Interview Questions
                  - Spring MVC Tutorial
                  - Spring MVC Interview Questions
                  - Hibernate Tutorial
                  - Hibernate Interview Questions
          + Programming Languages
              o C
              o C++
              o JavaScript
              o PHP
              o R Tutorial
              o C#
              o SQL
              o Scala
              o Perl
              o Go Language
              o Kotlin
          + System Design
              o System Design Tutorial
                  - What is System Design
                  - Key Terminologies in System Design
                  - Analysis and Architecture of Systems
                  - Scalability in System Design
                  - Databases in System Design
                  - High Level Design or HLD
                  - Low Level Design or LLD
                  - Case Studies in Designing Systems
                  - Complete System Design Tutorial
              o Software Design Patterns
              o System Design Roadmap
              o Top 10 System Design Interview Questions and Answers
          + Interview Corner
              o Company Preparation
              o Top Topics
              o Practice Company Questions
              o Interview Experiences
              o Experienced Interviews
              o Internship Interviews
              o Competitive Programming
              o Multiple Choice Quizzes
              o Aptitude for Placements
          + Computer Science Subjects
              o Operating System
              o DBMS
              o Computer Networks
              o Engineering Mathematics
              o Computer Organization and Architecture
              o Theory of Computation
              o Compiler Design
              o Digital Logic
              o Software Engineering
          + DevOps
              o GIT
              o AWS
              o Docker
              o Kubernetes
              o Microsoft Azure Tutorial
              o Google Cloud Platform
          + Linux
              o Linux Tutorial
              o Linux Commands A-Z
              o Linux Commands Cheatsheet
              o File Permission Commands
              o Linux System Administration
              o Linux File System
              o Linux Shell Scripting
              o Linux Networking
              o Linux Interview Questions
          + Software Testing
              o Software Testing Tutorial
              o Software Engineering Tutorial
              o Testing Interview Questions
              o Jira
          + Databases
              o DBMS Tutorial
              o SQL Tutorial
              o PostgreSQL Tutorial
              o MongoDB Tutorial
              o SQL Interview Questions
              o MySQL Interview Questions
              o PL/SQL Interview Questions
          + Android
              o Android Tutorial
              o Android Studio Tutorial
              o Kotlin For Android
              o Android Projects
              o Android Interview Questions
              o 6 Weeks of Android App Development
          + Excel
              o MS Excel Tutorial
              o Introduction to MS Excel
              o Data Analysis in Excel
              o Basic Excel Formulas & Functions
              o Data Analysis in Advanced Excel
              o Workbooks
              o Statistical Functions
              o Data Visualization in Excel
              o Pivot Tables in Excel
              o Excel Spreadsheets in Python
              o Basic Excel Shortcuts
          + Mathematics
              o Number System
              o Algebra
              o Linear Algebra
              o Trigonometry
              o Set Theory
              o Statistics
              o Probability
              o Geometry
              o Mensuration
              o Logarithms
              o Calculus
      * DSA
          + Data Structures
              o Arrays
              o Matrix
              o Strings
              o Linked List
                  - Singly Linked List
                  - Doubly Linked List
                  - Circular Linked List
                  - Doubly Circular Linked List
                  - Linked List Tutorial
              o Stack
              o Queue
              o Tree
                  - Generic Tree
                  - Binary Tree
                  - Binary Search Tree
                  - AVL Tree
                  - B Tree
                  - B+ Tree
                  - Red Black Tree
                  - Tree Data Structure Tutorial
              o Heap
              o Hashing
              o Graph
              o Set Data Structure
              o Map Data Structure
              o Advanced Data Structure
              o Data Structures Tutorial
          + Algorithms
              o Analysis of Algorithms
                  - Design and Analysis of Algorithms
                  - Asymptotic Analysis
                  - Asymptotic Notations
                  - Worst, Average and Best Cases
              o Searching Algorithms
                  - Linear Search
                  - Binary Search
                  - Searching Algorithms Tutorial
              o Sorting Algorithms
                  - Selection Sort
                  - Bubble Sort
                  - Insertion Sort
                  - Merge Sort
                  - Quick Sort
                  - Heap Sort
                  - Counting Sort
                  - Radix Sort
                  - Bucket Sort
                  - Sorting Algorithms Tutorial
              o Greedy Algorithms
              o Dynamic Programming
              o Graph Algorithms
              o Pattern Searching
              o Recursion
              o Backtracking
              o Divide and Conquer
              o Mathematical Algorithms
              o Geometric Algorithms
              o Bitwise Algorithms
              o Randomized Algorithms
              o Branch and Bound
              o Algorithms Tutorial
          + DSA Tutorial
          + Practice
              o All DSA Problems
              o Problem of the Day
              o Company Wise Coding Practice
                  - Amazon
                  - Microsoft
                  - Flipkart
                  - Explore All
              o GfG SDE Sheet
              o Practice Problems Difficulty Wise
                  - School
                  - Basic
                  - Easy
                  - Medium
                  - Hard
              o Language Wise Coding Practice
                  - CPP
                  - Java
                  - Python
              o Curated DSA Lists
                  - Beginner's DSA Sheet
                  - Top 50 Array Problems
                  - Top 50 String Problems
                  - Top 50 DP Problems
                  - Top 50 Graph Problems
                  - Top 50 Tree Problems
          + Competitive Programming
          + Company Wise SDE Sheets
              o Facebook SDE Sheet
              o Amazon SDE Sheet
              o Apple SDE Sheet
              o Netflix SDE Sheet
              o Google SDE Sheet
          + DSA Cheat Sheets
              o SDE Sheet
              o DSA Sheet for Beginners
              o FAANG Coding Sheet
              o Product-Based Coding Sheet
              o Company-Wise Preparation Sheet
          + Top Interview Questions
          + Puzzles
              o All Puzzles
              o Top 100 Puzzles Asked In Interviews
              o Top 20 Puzzles Commonly Asked During SDE Interviews
      * Data Science
          + Python Tutorial
          + R Tutorial
          + Machine Learning
          + Data Science using Python
          + Data Science using R
          + Data Science Packages
              o Pandas Tutorial
              o NumPy Tutorial
          + Data Visualization
              o Python Data Visualization Tutorial
              o Data Visualization with R
          + Data Analysis
              o Data Analysis with Python
              o Data Analysis with R
          + Deep Learning
          + NLP Tutorial
      * Web Tech
          + HTML Tutorial
          + CSS Tutorial
          + JavaScript Tutorial
          + PHP Tutorial
          + ReactJS Tutorial
          + NodeJS Tutorial
          + AngularJS Tutorial
          + Bootstrap Tutorial
          + Typescript
          + Web Development Using Python
              o Django
                  - Django Tutorial
                  - Django Projects
                  - Django Interview Questions
              o Flask
                  - Flask Tutorial
                  - Flask Projects
                  - Flask Interview Questions
              o Postman
              o Github
          + Wordpress Tutorial
          + Web Design
          + Cheat Sheets
              o HTML Cheat Sheet
              o CSS Cheat Sheet
              o JavaScript Cheat Sheet
              o React Cheat Sheet
              o Angular Cheat Sheet
              o jQuery Cheat Sheet
              o Bootstrap Cheat Sheet
          + Learn Complete Web Development
      * Courses
          + Coding for Everyone
          + DSA to Development
          + Machine Learning & Data Science
          + Generative AI & ChatGPT
          + Become AWS Certified
          + DSA Courses
              o Data Structure & Algorithm(C++/JAVA)
              o Data Structure & Algorithm(Python)
              o Data Structure & Algorithm(JavaScript)
          + Programming Languages
              o CPP
              o Java
              o Python
              o JavaScript
              o C
        * 
          * 
          * 
          * 
            + 
            + Python Basics
            + Interview Questions
            + Python Quiz
            + Popular Packages
            + Python Projects
            + Practice Python
            + AI With Python
            + Learn Python3
            + Python Automation
            + Python Web Dev
            + DSA with Python
            + Python OOPs
            + Lists
            + Strings
            + Dictionaries
        ▲
            Open In App

                          Multiprocessing in Python | Set 1 (Introduction)

                          Last Updated : 15 Sep, 2023
                          Improve


                          + 
                          + 
                          + 
                                Improve
                                Like Article
                                Like
                                Save
                              Share
                                Report

                        This article is a brief yet concise introduction to multiprocessing in Python programming language.

                        What is multiprocessing?

                        Multiprocessing refers to the ability of a system to support more than one processor at the same time. Applications in a multiprocessing system are broken to smaller routines that run independently. The operating system allocates these threads to the processors improving performance of the system.

                        Why multiprocessing?

                        Consider a computer system with a single processor. If it is assigned several processes at the same time, it will have to interrupt each task and switch briefly to another, to keep all of the processes going.
                        This situation is just like a chef working in a kitchen alone. He has to do several tasks like baking, stirring, kneading dough, etc.

                        So the gist is that: The more tasks you must do at once, the more difficult it gets to keep track of them all, and keeping the timing right becomes more of a challenge.
                        This is where the concept of multiprocessing arises!
                        A multiprocessing system can have:

                          + multiprocessor, i.e. a computer with more than one central processor.
                          + multi-core processor, i.e. a single computing component with two or more independent actual processing units (called “cores”).

                        Here, the CPU can easily executes several tasks at once, with each task using its own processor.

                        It is just like the chef in last situation being assisted by his assistants. Now, they can divide the tasks among themselves and chef doesn’t need to switch between his tasks.

                        Multiprocessing in Python

                        In Python, the multiprocessing module includes a very simple and intuitive API for dividing work between multiple processes.
                        Let us consider a simple example using multiprocessing module:




                                    # importing the multiprocessing module                        
                                    import multiprocessing                                        
                                    def print_cube(num):                                          
                                    """                                                           
                                    function to print cube of given num                           
                                    """                                                           
                                    print("Cube: {}".format(num * num * num))                     
                                    def print_square(num):                                        
                                    """                                                           
                                    function to print square of given num                         
                                    """                                                           
                                    print("Square: {}".format(num * num))                         
                                    if __name__ == "__main__":                                    
                                    # creating processes                                          
                                    p1 = multiprocessing.Process(target=print_square, args=(10, ))
                                    p2 = multiprocessing.Process(target=print_cube, args=(10, ))  
                                    # starting process 1                                          
                                    p1.start()                                                    
                                    # starting process 2                                          
                                    p2.start()                                                    
                                    # wait until process 1 is finished                            
                                    p1.join()                                                     
                                    # wait until process 2 is finished                            
                                    p2.join()                                                     
                                    # both processes finished                                     
                                    print("Done!")                                                
                                
                          Square: 100
                          Cube: 1000
                          Done!
                          

                          Let us try to understand the above code:

                            + To import the multiprocessing module, we do:
                              import multiprocessing
                              
                            + To create a process, we create an object of Process class. It takes following arguments:
                                o target: the function to be executed by process
                                o args: the arguments to be passed to the target function

                              Note: Process constructor takes many other arguments also which will be discussed later. In above example, we created 2 processes with different target functions:

                              p1 = multiprocessing.Process(target=print_square, args=(10, ))
                              p2 = multiprocessing.Process(target=print_cube, args=(10, ))
                              
                            + To start a process, we use start method of Process class.
                              p1.start()
                              p2.start()
                              
                            + Once the processes start, the current program also keeps on executing. In order to stop execution of current program until a process is complete, we use join method.
                              p1.join()
                              p2.join()
                              

                              As a result, the current program will first wait for the completion of p1 and then p2. Once, they are completed, the next statements of current program are executed.

                          Let us consider another program to understand the concept of different processes running on same python script. In this example below, we print the ID of the processes running the target functions:




                                      # importing the multiprocessing module                        
                                      import multiprocessing                                        
                                      import os                                                     
                                      def worker1():                                                
                                      # printing process id                                         
                                      print("ID of process running worker1: {}".format(os.getpid()))
                                      def worker2():                                                
                                      # printing process id                                         
                                      print("ID of process running worker2: {}".format(os.getpid()))
                                      if __name__ == "__main__":                                    
                                      # printing main program process id                            
                                      print("ID of main process: {}".format(os.getpid()))           
                                      # creating processes                                          
                                      p1 = multiprocessing.Process(target=worker1)                  
                                      p2 = multiprocessing.Process(target=worker2)                  
                                      # starting processes                                          
                                      p1.start()                                                    
                                      p2.start()                                                    
                                      # process IDs                                                 
                                      print("ID of process p1: {}".format(p1.pid))                  
                                      print("ID of process p2: {}".format(p2.pid))                  
                                      # wait until processes are finished                           
                                      p1.join()                                                     
                                      p2.join()                                                     
                                      # both processes finished                                     
                                      print("Both processes finished execution!")                   
                                      # check if processes are alive                                
                                      print("Process p1 is alive: {}".format(p1.is_alive()))        
                                      print("Process p2 is alive: {}".format(p2.is_alive()))        
                                  
                            ID of main process: 28628
                            ID of process running worker1: 29305
                            ID of process running worker2: 29306
                            ID of process p1: 29305
                            ID of process p2: 29306
                            Both processes finished execution!
                            Process p1 is alive: False
                            Process p2 is alive: False
                            
                              + The main python script has a different process ID and multiprocessing module spawns new processes with different process IDs as we create Process objects p1 and p2. In above program, we use os.getpid() function to get ID of process running the current target function.

                                Notice that it matches with the process IDs of p1 and p2 which we obtain using pid attribute of Process class.

                              + Each process runs independently and has its own memory space.
                              + As soon as the execution of target function is finished, the processes get terminated. In above program we used is_alive method of Process class to check if a process is still active or not.

                            Consider the diagram below to understand how new processes are different from main Python script:

                            So, this was a brief introduction to multiprocessing in Python. Next few articles will cover following topics related to multiprocessing:

                              + Sharing data between processes using Array, value and queues.
                              + Lock and Pool concepts in multiprocessing

                            Next:

                              + Multiprocessing in Python | Set 2
                              + Synchronization and Pooling of processes in Python

                            References:

                              + http://learn.parallax.com/tutorials/language/blocklyprop/blocklyprop-functions-and-multicore/bit-about-multicore
                              + https://docs.python.org/3/library/multiprocessing.html



                                      N

                                        Nikhil Kumar

                                  Improve


                                Next Article
                                  Multiple Sets Intersection in Python

                                    Please Login to comment...

                          Similar Reads

                                Python multiprocessing.Queue vs multiprocessing.manager().Queue()
                                In Python, the multiprocessing module allows for the creation of separate processes that can run concurrently on different cores of a computer. One of the ways to communicate between these processes is by using queues. The multiprocessing module provides two types of queues: The Queue class is a simple way to create a queue that can be used by mult
                              10 min read
                                Multiprocessing in Python | Set 2 (Communication between processes)
                                Multiprocessing in Python | Set 1 These articles discusses the concept of data sharing and message passing between processes while using multiprocessing module in Python. In multiprocessing, any newly created process will do following: run independently have their own memory space. Consider the program below to understand this concept: import multi
                              9 min read
                                Difference Between Multithreading vs Multiprocessing in Python
                                In this article, we will learn the what, why, and how of multithreading and multiprocessing in Python. Before we dive into the code, let us understand what these terms mean. A program is an executable file which consists of a set of instructions to perform some task and is usually stored on the disk of your computer.A process is what we call a prog
                              8 min read
                                Running Queries in Python Using Multiprocessing
                                Before diving into running queries using multiprocessing let’s understand what multiprocessing is in Python. Multiprocessing enables the computer to utilize multiple cores of a CPU to run tasks/processes in parallel. This parallelization leads to significant speedup in tasks that involve a lot of computation. Some of you might be wondering why don’
                              3 min read
                                Multithreading or Multiprocessing with Python and Selenium
                                Multithreading and multiprocessing are two popular approaches for improving the performance of a program by allowing it to run tasks in parallel. These approaches can be particularly useful when working with Python and Selenium, as they allow you to perform multiple actions simultaneously, such as automating the testing of a web application. In thi
                              11 min read
                                Understanding ‘fork’ and ‘spawn’ in Python Multiprocessing
                                Python’s multiprocessing library provides a powerful way to leverage multiple processor cores for concurrent execution, enhancing the performance of computationally intensive tasks. One of the intriguing aspects of multiprocessing is the ability to initiate new processes using various start methods. These start methods not only facilitate the creat
                              6 min read
                                Python Database Optimization with Psycopg2 and Multiprocessing
                                This article will provide a succinct overview of the fundamental utilization of the Psycopg2 module and the Multiprocessing module in Python. It will cover how Psycopg2 operates independently and in conjunction with multiprocessing. Psycopg2 and Its Role in Database OperationsAccording to PyPi's documentation for Psycopg2, it is designed to be used
                              6 min read
                                Multiprocessing with NumPy Arrays
                                Multiprocessing is a powerful tool that enables a computer to perform multiple tasks at the same time, improving overall performance and speed. In this article, we will see how we can use multiprocessing with NumPy arrays. NumPy is a library for the Python programming language that provides support for arrays and matrices. In many cases, working wi
                              5 min read
                                Multiprocessing in FastAPI
                                In this article, we are going to see what is multiprocessing, and how multiprocessing can utilize the system resources efficiently and can reduce the time taken to complete a big task. We will see the "concurrent.futures" module that is used for multiprocessing in FastAPI and then see how we can use it to download a big zip file from the server eff
                              5 min read
                                Array in Python | Set 1 (Introduction and Functions)
                                Other than some generic containers like lists, Python in its definition can also handle containers with specified data types. The array can be handled in Python by a module named "array". They can be useful when we have to manipulate only specific data type values. Properties of ArraysEach array element is of the same data type and size. For exampl
                              7 min read
                          View More Articles

                              Article Tags :
                              + Python

                              Practice Tags :
                              + python

                    A-143, 9th Floor, Sovereign Corporate Tower, Sector-136, Noida, Uttar Pradesh - 201305
                      + Company
                      + About Us
                      + Legal
                      + In Media
                      + Contact Us
                      + Advertise with us
                      + GFG Corporate Solution
                      + Placement Training Program
                      + Explore
                      + Hack-A-Thons
                      + GfG Weekly Contest
                      + DSA in JAVA/C++
                      + Master System Design
                      + Master CP
                      + GeeksforGeeks Videos
                      + Geeks Community
                      + Languages
                      + Python
                      + Java
                      + C++
                      + PHP
                      + GoLang
                      + SQL
                      + R Language
                      + Android Tutorial
                      + Tutorials Archive
                      + DSA
                      + Data Structures
                      + Algorithms
                      + DSA for Beginners
                      + Basic DSA Problems
                      + DSA Roadmap
                      + Top 100 DSA Interview Problems
                      + DSA Roadmap by Sandeep Jain
                      + All Cheat Sheets
                      + Data Science & ML
                      + Data Science With Python
                      + Data Science For Beginner
                      + Machine Learning Tutorial
                      + ML Maths
                      + Data Visualisation Tutorial
                      + Pandas Tutorial
                      + NumPy Tutorial
                      + NLP Tutorial
                      + Deep Learning Tutorial
                      + HTML & CSS
                      + HTML
                      + CSS
                      + Web Templates
                      + CSS Frameworks
                      + Bootstrap
                      + Tailwind CSS
                      + SASS
                      + LESS
                      + Web Design
                      + Python Tutorial
                      + Python Programming Examples
                      + Python Projects
                      + Python Tkinter
                      + Web Scraping
                      + OpenCV Tutorial
                      + Python Interview Question
                      + Django
                      + Computer Science
                      + Operating Systems
                      + Computer Network
                      + Database Management System
                      + Software Engineering
                      + Digital Logic Design
                      + Engineering Maths
                      + DevOps
                      + Git
                      + AWS
                      + Docker
                      + Kubernetes
                      + Azure
                      + GCP
                      + DevOps Roadmap
                      + Competitive Programming
                      + Top DS or Algo for CP
                      + Top 50 Tree
                      + Top 50 Graph
                      + Top 50 Array
                      + Top 50 String
                      + Top 50 DP
                      + Top 15 Websites for CP
                      + System Design
                      + High Level Design
                      + Low Level Design
                      + UML Diagrams
                      + Interview Guide
                      + Design Patterns
                      + OOAD
                      + System Design Bootcamp
                      + Interview Questions
                      + JavaScript
                      + JavaScript Examples
                      + TypeScript
                      + ReactJS
                      + NextJS
                      + AngularJS
                      + NodeJS
                      + Lodash
                      + Web Browser
                      + Preparation Corner
                      + Company-Wise Recruitment Process
                      + Resume Templates
                      + Aptitude Preparation
                      + Puzzles
                      + Company-Wise Preparation
                      + School Subjects
                      + Mathematics
                      + Physics
                      + Chemistry
                      + Biology
                      + Social Science
                      + English Grammar
                      + World GK
                      + Management & Finance
                      + Management
                      + HR Management
                      + Finance
                      + Organisational Behaviour
                      + Marketing
                      + Free Online Tools
                      + Typing Test
                      + Image Editor
                      + Code Formatters
                      + Code Converters
                      + Currency Converter
                      + Random Number Generator
                      + Random Password Generator
                      + More Tutorials
                      + Software Development
                      + Software Testing
                      + Product Management
                      + SEO - Search Engine Optimization
                      + Linux
                      + Excel
                      + All Cheatsheets
                      + GeeksforGeeks Videos
                      + DSA
                      + Python
                      + Java
                      + C++
                      + Web Development
                      + Data Science
                      + CS Subjects
                  @GeeksforGeeks, Sanchhaya Education Private Limited , All rights reserved
              We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy Got It !

                  What kind of Experience do you want to share?

                    Interview Experiences
                    Admission Experiences
                    Career Journeys
                    Work Experiences
                    Campus Experiences
                    Competitive Exam Experiences
                    Can't choose a topic to write? click here for suggested topics
                    Write and publish your own Article
This article is a brief yet concise introduction to multiprocessing in Python programming language.
 What is multiprocessing? 
Multiprocessing refers to the ability of a system to support more than one processor at the same time. Applications in a multiprocessing system are broken to smaller routines that run independently. The operating system allocates these threads to the processors improving performance of the system.
 Why multiprocessing? 
Consider a computer system with a single processor. If it is assigned several processes at the same time, it will have to interrupt each task and switch briefly to another, to keep all of the processes going.
This situation is just like a chef working in a kitchen alone. He has to do several tasks like baking, stirring, kneading dough, etc.
So the gist is that: The more tasks you must do at once, the more difficult it gets to keep track of them all, and keeping the timing right becomes more of a challenge.
This is where the concept of multiprocessing arises!
A multiprocessing system can have: 
multiprocessor, i.e. a computer with more than one central processor.
multi-core processor, i.e. a single computing component with two or more independent actual processing units (called “cores”).
Here, the CPU can easily executes several tasks at once, with each task using its own processor.
It is just like the chef in last situation being assisted by his assistants. Now, they can divide the tasks among themselves and chef doesn’t need to switch between his tasks.
 Multiprocessing in Python 
In Python, the  multiprocessing  module includes a very simple and intuitive API for dividing work between multiple processes.
Let us consider a simple example using multiprocessing module:
 import multiprocessing  
 def print_cube(num):  
      print ( "Cube: {}" . format (num  * num  * num))  
 def print_square(num):  
      print ( "Square: {}" . format (num  * num))  
 if __name__  = = "__main__" :  
      p1  = multiprocessing.Process(target = print_square, args = ( 10 , ))  
      p2  = multiprocessing.Process(target = print_cube, args = ( 10 , ))  
      p1.start()  
      p2.start()  
      p1.join()  
      p2.join()  
      print ( "Done!" )  
Square: 100
Cube: 1000
Done!
Let us try to understand the above code:
To import the multiprocessing module, we do:
import multiprocessing
To create a process, we create an object of Process class. It takes following arguments:
 target: the function to be executed by process
 args: the arguments to be passed to the target function
Note: Process constructor takes many other arguments also which will be discussed later. In above example, we created 2 processes with different target functions:
p1 = multiprocessing.Process(target=print_square, args=(10, ))
p2 = multiprocessing.Process(target=print_cube, args=(10, ))
To start a process, we use start method of Process class.
p1.start()
p2.start()
Once the processes start, the current program also keeps on executing. In order to stop execution of current program until a process is complete, we use join method.
p1.join()
p2.join()
As a result, the current program will first wait for the completion of p1 and then p2. Once, they are completed, the next statements of current program are executed. 
Let us consider another program to understand the concept of different processes running on same python script. In this example below, we print the ID of the processes running the target functions:
 import multiprocessing  
 import os  
 def worker1():  
      print ( "ID of process running worker1: {}" . format (os.getpid()))  
 def worker2():  
      print ( "ID of process running worker2: {}" . format (os.getpid()))  
 if __name__  = = "__main__" :  
      print ( "ID of main process: {}" . format (os.getpid()))  
      p1  = multiprocessing.Process(target = worker1)  
      p2  = multiprocessing.Process(target = worker2)  
      p1.start()  
      p2.start()  
      print ( "ID of process p1: {}" . format (p1.pid))  
      print ( "ID of process p2: {}" . format (p2.pid))  
      p1.join()  
      p2.join()  
      print ( "Both processes finished execution!" )  
      print ( "Process p1 is alive: {}" . format (p1.is_alive()))  
      print ( "Process p2 is alive: {}" . format (p2.is_alive()))  
ID of main process: 28628
ID of process running worker1: 29305
ID of process running worker2: 29306
ID of process p1: 29305
ID of process p2: 29306
Both processes finished execution!
Process p1 is alive: False
Process p2 is alive: False
The main python script has a different process ID and multiprocessing module spawns new processes with different process IDs as we create Process objects p1 and p2. In above program, we use os.getpid() function to get ID of process running the current target function.
Notice that it matches with the process IDs of p1 and p2 which we obtain using pid attribute of Process class. 
 Each process runs independently and has its own memory space. 
As soon as the execution of target function is finished, the processes get terminated. In above program we used is_alive method of Process class to check if a process is still active or not.
Consider the diagram below to understand how new processes are different from main Python script:
So, this was a brief introduction to multiprocessing in Python. Next few articles will cover following topics related to multiprocessing:
Sharing data between processes using Array, value and queues.
Lock and Pool concepts in multiprocessing
 Next: 
 Multiprocessing in Python | Set 2 
 Synchronization and Pooling of processes in Python 
 References: 
 http://learn.parallax.com/tutorials/language/blocklyprop/blocklyprop-functions-and-multicore/bit-about-multicore 
 https://docs.python.org/3/library/multiprocessing.html 
                                    
                                                                        
                            
                                  Please  Login  to comment...
Multiprocessing in Python | Set 1 (Introduction) - GeeksforGeeks
https://www.geeksforgeeks.org/multiprocessing-python-set-1/?ref=lbp
https://nathangrigg.com/2015/04/python-threading-vs-processes
Nathan Grigg
2015-04-08
About
<div>
<header>
 <h2><a href="https://nathangrigg.com/">Nathan Grigg</a></h2>
<nav>
	<ul>
 <li></li>
 <li><a href="https://nathangrigg.com/archive/">Archive</a></li>
 <li><a href="https://nathangrigg.com/feed/">RSS</a></li>
 <li><a href="https://mathstodon.xyz/@nathangrigg">Mastodon</a></li>
	</ul>
</nav>
</header>
<header>
<p><time>
	April 8, 2015</time>
</p></header>
<p>While <a href="https://nathangrigg.com/2015/04/basic-multithreaded-python/">adding multithreading support</a> to a Python script,
I found myself thinking again about the difference between multithreading and
multiprocessing in the context of Python.</p>
<p>For the uninitiated, Python multithreading uses <a href="http://en.wikipedia.org/wiki/Thread_(computing)">threads</a> to do parallel
processing.
This is the most common way to do parallel work in many programming languages.
But CPython has the <a href="https://wiki.python.org/moin/GlobalInterpreterLock">Global Interpreter Lock</a> (GIL), which means that
no two Python statements (bytecodes, strictly speaking) can execute at the same
time. So this form of parallelization is only
helpful if most of your threads are either not actively doing anything
(for example, waiting for input),
or doing something that happens outside the GIL
(for example launching a subprocess or doing a numpy calculation).
Using threads is very lightweight, for example, the threads share memory space.</p>
<p>Python multiprocessing, on the other hand, uses multiple system level processes,
that is, it starts up multiple instances of the Python interpreter.
This gets around the GIL limitation, but obviously has more overhead.
In addition, communicating between processes is not as easy as reading and
writing shared memory.</p>
<p>To illustrate the difference, I wrote two functions. The first is called <code>idle</code>
and simply sleeps for two seconds. The second is called <code>busy</code> and
computes a large sum. I ran each 15 times using 5 workers, once using threads
and once using processes. Then I used <a href="http://matplotlib.org/">matplotlib</a> to visualize the
results.</p>
<p>Here are the two <code>idle</code> graphs, which look essentially identical.
(Although if you look closely, you can see that the multiprocess version is
slightly slower.)</p>
<p>
</p>
<p>And here are the two <code>busy</code> graphs. The threads are clearly not helping
anything.</p>
<p>
</p>
<p>As is my custom these days, I did the computations in <a href="/images/2015/futures.html">an iPython notebook</a>.</p>
<hr />
||||I||||Nathan Grigg

 * About
 * Archive
 * RSS
 * Mastodon

Illustrating Python multithreading vs multiprocessing

April 8, 2015

While adding multithreading support to a Python script, I found myself thinking again about the difference between multithreading and multiprocessing in the context of Python.

For the uninitiated, Python multithreading uses threads to do parallel processing. This is the most common way to do parallel work in many programming languages. But CPython has the Global Interpreter Lock (GIL), which means that no two Python statements (bytecodes, strictly speaking) can execute at the same time. So this form of parallelization is only helpful if most of your threads are either not actively doing anything (for example, waiting for input), or doing something that happens outside the GIL (for example launching a subprocess or doing a numpy calculation). Using threads is very lightweight, for example, the threads share memory space.

Python multiprocessing, on the other hand, uses multiple system level processes, that is, it starts up multiple instances of the Python interpreter. This gets around the GIL limitation, but obviously has more overhead. In addition, communicating between processes is not as easy as reading and writing shared memory.

To illustrate the difference, I wrote two functions. The first is called idle and simply sleeps for two seconds. The second is called busy and computes a large sum. I ran each 15 times using 5 workers, once using threads and once using processes. Then I used matplotlib to visualize the results.

Here are the two idle graphs, which look essentially identical. (Although if you look closely, you can see that the multiprocess version is slightly slower.)

And here are the two busy graphs. The threads are clearly not helping anything.

As is my custom these days, I did the computations in an iPython notebook.

← Basic unobtrusive multithreading in Python

Filter App.net RSS →

Nathan Grigg 
	
  
  Archive 
  RSS 
  Mastodon 
	
 
	April 8, 2015
 
While adding multithreading support to a Python script,
I found myself thinking again about the difference between multithreading and
multiprocessing in the context of Python.
For the uninitiated, Python multithreading uses threads to do parallel
processing.
This is the most common way to do parallel work in many programming languages.
But CPython has the Global Interpreter Lock (GIL), which means that
no two Python statements (bytecodes, strictly speaking) can execute at the same
time. So this form of parallelization is only
helpful if most of your threads are either not actively doing anything
(for example, waiting for input),
or doing something that happens outside the GIL
(for example launching a subprocess or doing a numpy calculation).
Using threads is very lightweight, for example, the threads share memory space.
Python multiprocessing, on the other hand, uses multiple system level processes,
that is, it starts up multiple instances of the Python interpreter.
This gets around the GIL limitation, but obviously has more overhead.
In addition, communicating between processes is not as easy as reading and
writing shared memory.
To illustrate the difference, I wrote two functions. The first is called idle
and simply sleeps for two seconds. The second is called busy and
computes a large sum. I ran each 15 times using 5 workers, once using threads
and once using processes. Then I used matplotlib to visualize the
results.
Here are the two idle graphs, which look essentially identical.
(Although if you look closely, you can see that the multiprocess version is
slightly slower.)
And here are the two busy graphs. The threads are clearly not helping
anything.
As is my custom these days, I did the computations in an iPython notebook.
Nathan Grigg
https://nathangrigg.com/2015/04/python-threading-vs-processes
https://docs.python.org/3.3/c-api/init.html?highlight=gil
Initialization, Finalization, and Threads — Python 3.3.7 documentation
2017-09-19
None
<div><div>
<div>
<h2>Initializing and finalizing the interpreter<a href="#initializing-and-finalizing-the-interpreter">¶</a></h2>
<dl>
<dt>
void <a href="#Py_Initialize">¶</a></dt>
<dd><p>Initialize the Python interpreter. In an application embedding Python, this
should be called before using any other Python/C API functions; with the
exception of <a href="#Py_SetProgramName"></a>, <a href="#Py_SetPythonHome"></a> and <a href="#Py_SetPath"></a>. This initializes
the table of loaded modules (), and creates the fundamental
modules <a href="https://docs.python.org/3.3/library/builtins.html#module-builtins"></a>, <a href="https://docs.python.org/3.3/library/__main__.html#module-__main__"></a> and <a href="https://docs.python.org/3.3/library/sys.html#module-sys"></a>. It also initializes
the module search path (). It does not set ; use
<a href="#PySys_SetArgvEx"></a> for that. This is a no-op when called for a second time
(without calling <a href="#Py_Finalize"></a> first). There is no return value; it is a
fatal error if the initialization fails.</p>
</dd></dl>
<dl>
<dt>
void int<em> initsigs</em><a href="#Py_InitializeEx">¶</a></dt>
<dd><p>This function works like <a href="#Py_Initialize"></a> if <em>initsigs</em> is 1. If
<em>initsigs</em> is 0, it skips initialization registration of signal handlers, which
might be useful when Python is embedded.</p>
</dd></dl>
<dl>
<dt>
int <a href="#Py_IsInitialized">¶</a></dt>
<dd><p>Return true (nonzero) when the Python interpreter has been initialized, false
(zero) if not. After <a href="#Py_Finalize"></a> is called, this returns false until
<a href="#Py_Initialize"></a> is called again.</p>
</dd></dl>
<dl>
<dt>
void <a href="#Py_Finalize">¶</a></dt>
<dd><p>Undo all initializations made by <a href="#Py_Initialize"></a> and subsequent use of
Python/C API functions, and destroy all sub-interpreters (see
<a href="#Py_NewInterpreter"></a> below) that were created and not yet destroyed since
the last call to <a href="#Py_Initialize"></a>. Ideally, this frees all memory
allocated by the Python interpreter. This is a no-op when called for a second
time (without calling <a href="#Py_Initialize"></a> again first). There is no return
value; errors during finalization are ignored.</p>
<p>This function is provided for a number of reasons. An embedding application
might want to restart Python without having to restart the application itself.
An application that has loaded the Python interpreter from a dynamically
loadable library (or DLL) might want to free all memory allocated by Python
before unloading the DLL. During a hunt for memory leaks in an application a
developer might want to free all memory allocated by Python before exiting from
the application.</p>
<p><strong>Bugs and caveats:</strong> The destruction of modules and objects in modules is done
in random order; this may cause destructors (<a href="https://docs.python.org/3.3/reference/datamodel.html#object.__del__"></a> methods) to fail
when they depend on other objects (even functions) or modules. Dynamically
loaded extension modules loaded by Python are not unloaded. Small amounts of
memory allocated by the Python interpreter may not be freed (if you find a leak,
please report it). Memory tied up in circular references between objects is not
freed. Some memory allocated by extension modules may not be freed. Some
extensions may not work properly if their initialization routine is called more
than once; this can happen if an application calls <a href="#Py_Initialize"></a> and
<a href="#Py_Finalize"></a> more than once.</p>
</dd></dl>
</div>
<div>
<h2>Process-wide parameters<a href="#process-wide-parameters">¶</a></h2>
<dl>
<dt>
void wchar_t<em> *name</em><a href="#Py_SetProgramName">¶</a></dt>
<dd><p>This function should be called before <a href="#Py_Initialize"></a> is called for
the first time, if it is called at all. It tells the interpreter the value
of the argument to the function of the program
(converted to wide characters).
This is used by <a href="#Py_GetPath"></a> and some other functions below to find
the Python run-time libraries relative to the interpreter executable. The
default value is . The argument should point to a
zero-terminated wide character string in static storage whose contents will not
change for the duration of the program’s execution. No code in the Python
interpreter will change the contents of this storage.</p>
</dd></dl>
<dl>
<dt>
wchar* <a href="#Py_GetProgramName">¶</a></dt>
<dd><p>Return the program name set with <a href="#Py_SetProgramName"></a>, or the default.
The returned string points into static storage; the caller should not modify its
value.</p>
</dd></dl>
<dl>
<dt>
wchar_t* <a href="#Py_GetPrefix">¶</a></dt>
<dd><p>Return the <em>prefix</em> for installed platform-independent files. This is derived
through a number of complicated rules from the program name set with
<a href="#Py_SetProgramName"></a> and some environment variables; for example, if the
program name is , the prefix is . The
returned string points into static storage; the caller should not modify its
value. This corresponds to the <strong>prefix</strong> variable in the top-level
 and the argument to the <strong>configure</strong>
script at build time. The value is available to Python code as .
It is only useful on Unix. See also the next function.</p>
</dd></dl>
<dl>
<dt>
wchar_t* <a href="#Py_GetExecPrefix">¶</a></dt>
<dd><p>Return the <em>exec-prefix</em> for installed platform-<em>dependent</em> files. This is
derived through a number of complicated rules from the program name set with
<a href="#Py_SetProgramName"></a> and some environment variables; for example, if the
program name is , the exec-prefix is
. The returned string points into static storage; the caller
should not modify its value. This corresponds to the <strong>exec_prefix</strong>
variable in the top-level and the 
argument to the <strong>configure</strong> script at build time. The value is
available to Python code as . It is only useful on Unix.</p>
<p>Background: The exec-prefix differs from the prefix when platform dependent
files (such as executables and shared libraries) are installed in a different
directory tree. In a typical installation, platform dependent files may be
installed in the subtree while platform independent may
be installed in .</p>
<p>Generally speaking, a platform is a combination of hardware and software
families, e.g. Sparc machines running the Solaris 2.x operating system are
considered the same platform, but Intel machines running Solaris 2.x are another
platform, and Intel machines running Linux are yet another platform. Different
major revisions of the same operating system generally also form different
platforms. Non-Unix operating systems are a different story; the installation
strategies on those systems are so different that the prefix and exec-prefix are
meaningless, and set to the empty string. Note that compiled Python bytecode
files are platform independent (but not independent from the Python version by
which they were compiled!).</p>
<p>System administrators will know how to configure the <strong>mount</strong> or
<strong>automount</strong> programs to share between platforms
while having be a different filesystem for each
platform.</p>
</dd></dl>
<dl>
<dt>
wchar_t* <a href="#Py_GetProgramFullPath">¶</a></dt>
<dd><p>Return the full program name of the Python executable; this is computed as a
side-effect of deriving the default module search path from the program name
(set by <a href="#Py_SetProgramName"></a> above). The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as .</p>
</dd></dl>
<dl>
<dt>
wchar_t* <a href="#Py_GetPath">¶</a></dt>
<dd><p>Return the default module search path; this is computed from the program name
(set by <a href="#Py_SetProgramName"></a> above) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is 
on Unix and Mac OS X, on Windows. The returned string points into
static storage; the caller should not modify its value. The list
<a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a> is initialized with this value on interpreter startup; it
can be (and usually is) modified later to change the search path for loading
modules.</p>
</dd></dl>
<dl>
<dt>
void const wchar_t<em> *</em><a href="#Py_SetPath">¶</a></dt>
<dd><p>Set the default module search path. If this function is called before
<a href="#Py_Initialize"></a>, then <a href="#Py_GetPath"></a> won’t attempt to compute a
default search path but uses the one provided instead. This is useful if
Python is embedded by an application that has full knowledge of the location
of all modules. The path components should be separated by semicolons.</p>
<p>This also causes <a href="https://docs.python.org/3.3/library/sys.html#sys.executable"></a> to be set only to the raw program
name (see <a href="#Py_SetProgramName"></a>) and for <a href="https://docs.python.org/3.3/library/sys.html#sys.prefix"></a> and
<a href="https://docs.python.org/3.3/library/sys.html#sys.exec_prefix"></a> to be empty. It is up to the caller to modify these
if required after calling <a href="#Py_Initialize"></a>.</p>
</dd></dl>
<dl>
<dt>
const char* <a href="#Py_GetVersion">¶</a></dt>
<dd><p>Return the version of this Python interpreter. This is a string that looks
something like</p>
<div><pre>
</pre></div>
<p>The first word (up to the first space character) is the current Python version;
the first three characters are the major and minor version separated by a
period. The returned string points into static storage; the caller should not
modify its value. The value is available to Python code as <a href="https://docs.python.org/3.3/library/sys.html#sys.version"></a>.</p>
</dd></dl>
<dl>
<dt>
const char* <a href="#Py_GetPlatform">¶</a></dt>
<dd><p>Return the platform identifier for the current platform. On Unix, this is
formed from the “official” name of the operating system, converted to lower
case, followed by the major revision number; e.g., for Solaris 2.x, which is
also known as SunOS 5.x, the value is . On Mac OS X, it is
. On Windows, it is . The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as .</p>
</dd></dl>
<dl>
<dt>
const char* <a href="#Py_GetCopyright">¶</a></dt>
<dd><p>Return the official copyright string for the current Python version, for example</p>
<p></p>
<p>The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as .</p>
</dd></dl>
<dl>
<dt>
const char* <a href="#Py_GetCompiler">¶</a></dt>
<dd><p>Return an indication of the compiler used to build the current Python version,
in square brackets, for example:</p>
<p>The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as part of the variable
.</p>
</dd></dl>
<dl>
<dt>
const char* <a href="#Py_GetBuildInfo">¶</a></dt>
<dd><p>Return information about the sequence number and build date and time of the
current Python interpreter instance, for example</p>
<div><pre>
</pre></div>
<p>The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as part of the variable
.</p>
</dd></dl>
<dl>
<dt>
void int<em> argc</em>, wchar_t<em> **argv</em>, int<em> updatepath</em><a href="#PySys_SetArgvEx">¶</a></dt>
<dd><p>Set <a href="https://docs.python.org/3.3/library/sys.html#sys.argv"></a> based on <em>argc</em> and <em>argv</em>. These parameters are
similar to those passed to the program’s function with the
difference that the first entry should refer to the script file to be
executed rather than the executable hosting the Python interpreter. If there
isn’t a script that will be run, the first entry in <em>argv</em> can be an empty
string. If this function fails to initialize <a href="https://docs.python.org/3.3/library/sys.html#sys.argv"></a>, a fatal
condition is signalled using <a href="https://docs.python.org/3.3/c-api/sys.html#Py_FatalError"></a>.</p>
<p>If <em>updatepath</em> is zero, this is all the function does. If <em>updatepath</em>
is non-zero, the function also modifies <a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a> according to the
following algorithm:</p>
<ul>
<li>If the name of an existing script is passed in , the absolute
path of the directory where the script is located is prepended to
<a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a>.</li>
<li>Otherwise (that is, if <em>argc</em> is 0 or doesn’t point
to an existing file name), an empty string is prepended to
<a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a>, which is the same as prepending the current working
directory ().</li>
</ul>
<div>
<p>Note</p>
<p>It is recommended that applications embedding the Python interpreter
for purposes other than executing a single script pass 0 as <em>updatepath</em>,
and update <a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a> themselves if desired.
See <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-5983">CVE-2008-5983</a>.</p>
<p>On versions before 3.1.3, you can achieve the same effect by manually
popping the first <a href="https://docs.python.org/3.3/library/sys.html#sys.path"></a> element after having called
<a href="#PySys_SetArgv"></a>, for example using:</p>
<div><pre>
</pre></div>
</div>
<p></p>
</dd></dl>
<dl>
<dt>
void int<em> argc</em>, wchar_t<em> **argv</em><a href="#PySys_SetArgv">¶</a></dt>
<dd><p>This function works like <a href="#PySys_SetArgvEx"></a> with <em>updatepath</em> set to 1.</p>
</dd></dl>
<dl>
<dt>
void wchar_t<em> *home</em><a href="#Py_SetPythonHome">¶</a></dt>
<dd><p>Set the default “home” directory, that is, the location of the standard
Python libraries. See <a href="https://docs.python.org/3.3/using/cmdline.html#envvar-PYTHONHOME"></a> for the meaning of the
argument string.</p>
<p>The argument should point to a zero-terminated character string in static
storage whose contents will not change for the duration of the program’s
execution. No code in the Python interpreter will change the contents of
this storage.</p>
</dd></dl>
<dl>
<dt>
w_char* <a href="#Py_GetPythonHome">¶</a></dt>
<dd><p>Return the default “home”, that is, the value set by a previous call to
<a href="#Py_SetPythonHome"></a>, or the value of the <a href="https://docs.python.org/3.3/using/cmdline.html#envvar-PYTHONHOME"></a>
environment variable if it is set.</p>
</dd></dl>
</div>
<div>
<h2>Thread State and the Global Interpreter Lock<a href="#thread-state-and-the-global-interpreter-lock">¶</a></h2>
<p>The Python interpreter is not fully thread-safe. In order to support
multi-threaded Python programs, there’s a global lock, called the <a href="https://docs.python.org/3.3/glossary.html#term-global-interpreter-lock"><em>global
interpreter lock</em></a> or <a href="https://docs.python.org/3.3/glossary.html#term-gil"><em>GIL</em></a>, that must be held by the current thread before
it can safely access Python objects. Without the lock, even the simplest
operations could cause problems in a multi-threaded program: for example, when
two threads simultaneously increment the reference count of the same object, the
reference count could end up being incremented only once instead of twice.</p>
<p>Therefore, the rule exists that only the thread that has acquired the
<a href="https://docs.python.org/3.3/glossary.html#term-gil"><em>GIL</em></a> may operate on Python objects or call Python/C API functions.
In order to emulate concurrency of execution, the interpreter regularly
tries to switch threads (see <a href="https://docs.python.org/3.3/library/sys.html#sys.setswitchinterval"></a>). The lock is also
released around potentially blocking I/O operations like reading or writing
a file, so that other Python threads can run in the meantime.</p>
<p>The Python interpreter keeps some thread-specific bookkeeping information
inside a data structure called <a href="#PyThreadState"></a>. There’s also one
global variable pointing to the current <a href="#PyThreadState"></a>: it can
be retrieved using <a href="#PyThreadState_Get"></a>.</p>
<div>
<h3>Releasing the GIL from extension code<a href="#releasing-the-gil-from-extension-code">¶</a></h3>
<p>Most extension code manipulating the <a href="https://docs.python.org/3.3/glossary.html#term-gil"><em>GIL</em></a> has the following simple
structure:</p>
<div><pre> 
 
 
 
 
</pre></div>
<p>This is so common that a pair of macros exists to simplify it:</p>
<div><pre>
 
</pre></div>
<p>The <a href="#Py_BEGIN_ALLOW_THREADS"></a> macro opens a new block and declares a
hidden local variable; the <a href="#Py_END_ALLOW_THREADS"></a> macro closes the
block. These two macros are still available when Python is compiled without
thread support (they simply have an empty expansion).</p>
<p>When thread support is enabled, the block above expands to the following code:</p>
<div><pre> 
 
 
</pre></div>
<p>Here is how these functions work: the global interpreter lock is used to protect the pointer to the
current thread state. When releasing the lock and saving the thread state,
the current thread state pointer must be retrieved before the lock is released
(since another thread could immediately acquire the lock and store its own thread
state in the global variable). Conversely, when acquiring the lock and restoring
the thread state, the lock must be acquired before storing the thread state
pointer.</p>
<div>
<p>Note</p>
<p>Calling system I/O functions is the most common use case for releasing
the GIL, but it can also be useful before calling long-running computations
which don’t need access to Python objects, such as compression or
cryptographic functions operating over memory buffers. For example, the
standard <a href="https://docs.python.org/3.3/library/zlib.html#module-zlib"></a> and <a href="https://docs.python.org/3.3/library/hashlib.html#module-hashlib"></a> modules release the GIL when
compressing or hashing data.</p>
</div>
</div>
<div>
<h3>Non-Python created threads<a href="#non-python-created-threads">¶</a></h3>
<p>When threads are created using the dedicated Python APIs (such as the
<a href="https://docs.python.org/3.3/library/threading.html#module-threading"></a> module), a thread state is automatically associated to them
and the code showed above is therefore correct. However, when threads are
created from C (for example by a third-party library with its own thread
management), they don’t hold the GIL, nor is there a thread state structure
for them.</p>
<p>If you need to call Python code from these threads (often this will be part
of a callback API provided by the aforementioned third-party library),
you must first register these threads with the interpreter by
creating a thread state data structure, then acquiring the GIL, and finally
storing their thread state pointer, before you can start using the Python/C
API. When you are done, you should reset the thread state pointer, release
the GIL, and finally free the thread state data structure.</p>
<p>The <a href="#PyGILState_Ensure"></a> and <a href="#PyGILState_Release"></a> functions do
all of the above automatically. The typical idiom for calling into Python
from a C thread is:</p>
<div><pre> 
 
 
</pre></div>
<p>Note that the functions assume there is only one global
interpreter (created automatically by <a href="#Py_Initialize"></a>). Python
supports the creation of additional interpreters (using
<a href="#Py_NewInterpreter"></a>), but mixing multiple interpreters and the
 API is unsupported.</p>
<p>Another important thing to note about threads is their behaviour in the face
of the C call. On most systems with , after a
process forks only the thread that issued the fork will exist. That also
means any locks held by other threads will never be released. Python solves
this for <a href="https://docs.python.org/3.3/library/os.html#os.fork"></a> by acquiring the locks it uses internally before
the fork, and releasing them afterwards. In addition, it resets any
<a href="https://docs.python.org/3.3/library/threading.html#lock-objects"><em>Lock Objects</em></a> in the child. When extending or embedding Python, there
is no way to inform Python of additional (non-Python) locks that need to be
acquired before or reset after a fork. OS facilities such as
 would need to be used to accomplish the same thing.
Additionally, when extending or embedding Python, calling 
directly rather than through <a href="https://docs.python.org/3.3/library/os.html#os.fork"></a> (and returning to or calling
into Python) may result in a deadlock by one of Python’s internal locks
being held by a thread that is defunct after the fork.
<a href="https://docs.python.org/3.3/c-api/sys.html#PyOS_AfterFork"></a> tries to reset the necessary locks, but is not
always able to.</p>
</div>
<div>
<h3>High-level API<a href="#high-level-api">¶</a></h3>
<p>These are the most commonly used types and functions when writing C extension
code, or when embedding the Python interpreter:</p>
<dl>
<dt>
<a href="#PyInterpreterState">¶</a></dt>
<dd><p>This data structure represents the state shared by a number of cooperating
threads. Threads belonging to the same interpreter share their module
administration and a few other internal items. There are no public members in
this structure.</p>
<p>Threads belonging to different interpreters initially share nothing, except
process state like available memory, open file descriptors and such. The global
interpreter lock is also shared by all threads, regardless of to which
interpreter they belong.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">¶</a></dt>
<dd><p>This data structure represents the state of a single thread. The only public
data member is <a href="#PyInterpreterState"></a>, which points to
this thread’s interpreter state.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyEval_InitThreads">¶</a></dt>
<dd><p>Initialize and acquire the global interpreter lock. It should be called in the
main thread before creating a second thread or engaging in any other thread
operations such as . It is not needed before
calling <a href="#PyEval_SaveThread"></a> or <a href="#PyEval_RestoreThread"></a>.</p>
<p>This is a no-op when called for a second time.</p>
<p>This function cannot be called before <a href="#Py_Initialize"></a> anymore.</p>
<div>
<p>Note</p>
<p>When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock
operations slow the interpreter down a bit. Therefore, the lock is not
created initially. This situation is equivalent to having acquired the lock:
when there is only a single thread, all object accesses are safe. Therefore,
when this function initializes the global interpreter lock, it also acquires
it. Before the Python <a href="https://docs.python.org/3.3/library/_thread.html#module-_thread"></a> module creates a new thread, knowing
that either it has the lock or the lock hasn’t been created yet, it calls
<a href="#PyEval_InitThreads"></a>. When this call returns, it is guaranteed that
the lock has been created and that the calling thread has acquired it.</p>
<p>It is <strong>not</strong> safe to call this function when it is unknown which thread (if
any) currently has the global interpreter lock.</p>
<p>This function is not available when thread support is disabled at compile time.</p>
</div>
</dd></dl>
<dl>
<dt>
int <a href="#PyEval_ThreadsInitialized">¶</a></dt>
<dd><p>Returns a non-zero value if <a href="#PyEval_InitThreads"></a> has been called. This
function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyEval_SaveThread">¶</a></dt>
<dd><p>Release the global interpreter lock (if it has been created and thread
support is enabled) and reset the thread state to <em>NULL</em>, returning the
previous thread state (which is not <em>NULL</em>). If the lock has been created,
the current thread must have acquired it. (This function is available even
when thread support is disabled at compile time.)</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyEval_RestoreThread">¶</a></dt>
<dd><p>Acquire the global interpreter lock (if it has been created and thread
support is enabled) and set the thread state to <em>tstate</em>, which must not be
<em>NULL</em>. If the lock has been created, the current thread must not have
acquired it, otherwise deadlock ensues. (This function is available even
when thread support is disabled at compile time.)</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyThreadState_Get">¶</a></dt>
<dd><p>Return the current thread state. The global interpreter lock must be held.
When the current thread state is <em>NULL</em>, this issues a fatal error (so that
the caller needn’t check for <em>NULL</em>).</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyThreadState_Swap">¶</a></dt>
<dd><p>Swap the current thread state with the thread state given by the argument
<em>tstate</em>, which may be <em>NULL</em>. The global interpreter lock must be held
and is not released.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyEval_ReInitThreads">¶</a></dt>
<dd><p>This function is called from <a href="https://docs.python.org/3.3/c-api/sys.html#PyOS_AfterFork"></a> to ensure that newly
created child processes don’t hold locks referring to threads which
are not running in the child process.</p>
</dd></dl>
<p>The following functions use thread-local storage, and are not compatible
with sub-interpreters:</p>
<dl>
<dt>
PyGILState_STATE <a href="#PyGILState_Ensure">¶</a></dt>
<dd><p>Ensure that the current thread is ready to call the Python C API regardless
of the current state of Python, or of the global interpreter lock. This may
be called as many times as desired by a thread as long as each call is
matched with a call to <a href="#PyGILState_Release"></a>. In general, other
thread-related APIs may be used between <a href="#PyGILState_Ensure"></a> and
<a href="#PyGILState_Release"></a> calls as long as the thread state is restored to
its previous state before the Release(). For example, normal usage of the
<a href="#Py_BEGIN_ALLOW_THREADS"></a> and <a href="#Py_END_ALLOW_THREADS"></a> macros is
acceptable.</p>
<p>The return value is an opaque “handle” to the thread state when
<a href="#PyGILState_Ensure"></a> was called, and must be passed to
<a href="#PyGILState_Release"></a> to ensure Python is left in the same state. Even
though recursive calls are allowed, these handles <em>cannot</em> be shared - each
unique call to <a href="#PyGILState_Ensure"></a> must save the handle for its call
to <a href="#PyGILState_Release"></a>.</p>
<p>When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.</p>
</dd></dl>
<dl>
<dt>
void PyGILState_STATE<a href="#PyGILState_Release">¶</a></dt>
<dd><p>Release any resources previously acquired. After this call, Python’s state will
be the same as it was prior to the corresponding <a href="#PyGILState_Ensure"></a> call
(but generally this state will be unknown to the caller, hence the use of the
GILState API).</p>
<p>Every call to <a href="#PyGILState_Ensure"></a> must be matched by a call to
<a href="#PyGILState_Release"></a> on the same thread.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyGILState_GetThisThreadState">¶</a></dt>
<dd><p>Get the current thread state for this thread. May return if no
GILState API has been used on the current thread. Note that the main thread
always has such a thread-state, even if no auto-thread-state call has been
made on the main thread. This is mainly a helper/diagnostic function.</p>
</dd></dl>
<p>The following macros are normally used without a trailing semicolon; look for
example usage in the Python source distribution.</p>
<dl>
<dt>
<a href="#Py_BEGIN_ALLOW_THREADS">¶</a></dt>
<dd><p>This macro expands to .
Note that it contains an opening brace; it must be matched with a following
<a href="#Py_END_ALLOW_THREADS"></a> macro. See above for further discussion of this
macro. It is a no-op when thread support is disabled at compile time.</p>
</dd></dl>
<dl>
<dt>
<a href="#Py_END_ALLOW_THREADS">¶</a></dt>
<dd><p>This macro expands to . Note that it contains
a closing brace; it must be matched with an earlier
<a href="#Py_BEGIN_ALLOW_THREADS"></a> macro. See above for further discussion of
this macro. It is a no-op when thread support is disabled at compile time.</p>
</dd></dl>
<dl>
<dt>
<a href="#Py_BLOCK_THREADS">¶</a></dt>
<dd><p>This macro expands to : it is equivalent to
<a href="#Py_END_ALLOW_THREADS"></a> without the closing brace. It is a no-op when
thread support is disabled at compile time.</p>
</dd></dl>
<dl>
<dt>
<a href="#Py_UNBLOCK_THREADS">¶</a></dt>
<dd><p>This macro expands to : it is equivalent to
<a href="#Py_BEGIN_ALLOW_THREADS"></a> without the opening brace and variable
declaration. It is a no-op when thread support is disabled at compile time.</p>
</dd></dl>
</div>
<div>
<h3>Low-level API<a href="#low-level-api">¶</a></h3>
<p>All of the following functions are only available when thread support is enabled
at compile time, and must be called only when the global interpreter lock has
been created.</p>
<dl>
<dt>
<a href="#PyInterpreterState">PyInterpreterState</a>* <a href="#PyInterpreterState_New">¶</a></dt>
<dd><p>Create a new interpreter state object. The global interpreter lock need not
be held, but may be held if it is necessary to serialize calls to this
function.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyInterpreterState">PyInterpreterState</a><em> *interp</em><a href="#PyInterpreterState_Clear">¶</a></dt>
<dd><p>Reset all information in an interpreter state object. The global interpreter
lock must be held.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyInterpreterState">PyInterpreterState</a><em> *interp</em><a href="#PyInterpreterState_Delete">¶</a></dt>
<dd><p>Destroy an interpreter state object. The global interpreter lock need not be
held. The interpreter state must have been reset with a previous call to
<a href="#PyInterpreterState_Clear"></a>.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyInterpreterState">PyInterpreterState</a><em> *interp</em><a href="#PyThreadState_New">¶</a></dt>
<dd><p>Create a new thread state object belonging to the given interpreter object.
The global interpreter lock need not be held, but may be held if it is
necessary to serialize calls to this function.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyThreadState_Clear">¶</a></dt>
<dd><p>Reset all information in a thread state object. The global interpreter lock
must be held.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyThreadState_Delete">¶</a></dt>
<dd><p>Destroy a thread state object. The global interpreter lock need not be held.
The thread state must have been reset with a previous call to
<a href="#PyThreadState_Clear"></a>.</p>
</dd></dl>
<dl>
<dt>
<a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a>* <a href="#PyThreadState_GetDict">¶</a></dt>
<dd><em>Return value: Borrowed reference.</em><p>Return a dictionary in which extensions can store thread-specific state
information. Each extension should use a unique key to use to store state in
the dictionary. It is okay to call this function when no current thread state
is available. If this function returns <em>NULL</em>, no exception has been raised and
the caller should assume no current thread state is available.</p>
</dd></dl>
<dl>
<dt>
int long<em> id</em>, <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *exc</em><a href="#PyThreadState_SetAsyncExc">¶</a></dt>
<dd><p>Asynchronously raise an exception in a thread. The <em>id</em> argument is the thread
id of the target thread; <em>exc</em> is the exception object to be raised. This
function does not steal any references to <em>exc</em>. To prevent naive misuse, you
must write your own C extension to call this. Must be called with the GIL held.
Returns the number of thread states modified; this is normally one, but will be
zero if the thread id isn’t found. If <em>exc</em> is , the pending
exception (if any) for the thread is cleared. This raises no exceptions.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyEval_AcquireThread">¶</a></dt>
<dd><p>Acquire the global interpreter lock and set the current thread state to
<em>tstate</em>, which should not be <em>NULL</em>. The lock must have been created earlier.
If this thread already has the lock, deadlock ensues.</p>
<p><a href="#PyEval_RestoreThread"></a> is a higher-level function which is always
available (even when thread support isn’t enabled or when threads have
not been initialized).</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyEval_ReleaseThread">¶</a></dt>
<dd><p>Reset the current thread state to <em>NULL</em> and release the global interpreter
lock. The lock must have been created earlier and must be held by the current
thread. The <em>tstate</em> argument, which must not be <em>NULL</em>, is only used to check
that it represents the current thread state — if it isn’t, a fatal error is
reported.</p>
<p><a href="#PyEval_SaveThread"></a> is a higher-level function which is always
available (even when thread support isn’t enabled or when threads have
not been initialized).</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyEval_AcquireLock">¶</a></dt>
<dd><p>Acquire the global interpreter lock. The lock must have been created earlier.
If this thread already has the lock, a deadlock ensues.</p>
<p>This function does not update the current thread state. Please use
<a href="#PyEval_RestoreThread"></a> or <a href="#PyEval_AcquireThread"></a>
instead.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyEval_ReleaseLock">¶</a></dt>
<dd><p>Release the global interpreter lock. The lock must have been created earlier.</p>
<p>This function does not update the current thread state. Please use
<a href="#PyEval_SaveThread"></a> or <a href="#PyEval_ReleaseThread"></a>
instead.</p>
</dd></dl>
</div>
</div>
<div>
<h2>Sub-interpreter support<a href="#sub-interpreter-support">¶</a></h2>
<p>While in most uses, you will only embed a single Python interpreter, there
are cases where you need to create several independent interpreters in the
same process and perhaps even in the same thread. Sub-interpreters allow
you to do that. You can switch between sub-interpreters using the
<a href="#PyThreadState_Swap"></a> function. You can create and destroy them
using the following functions:</p>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#Py_NewInterpreter">¶</a></dt>
<dd><p>Create a new sub-interpreter. This is an (almost) totally separate environment
for the execution of Python code. In particular, the new interpreter has
separate, independent versions of all imported modules, including the
fundamental modules <a href="https://docs.python.org/3.3/library/builtins.html#module-builtins"></a>, <a href="https://docs.python.org/3.3/library/__main__.html#module-__main__"></a> and <a href="https://docs.python.org/3.3/library/sys.html#module-sys"></a>. The
table of loaded modules () and the module search path
() are also separate. The new environment has no 
variable. It has new standard I/O stream file objects ,
 and (however these refer to the same underlying
file descriptors).</p>
<p>The return value points to the first thread state created in the new
sub-interpreter. This thread state is made in the current thread state.
Note that no actual thread is created; see the discussion of thread states
below. If creation of the new interpreter is unsuccessful, <em>NULL</em> is
returned; no exception is set since the exception state is stored in the
current thread state and there may not be a current thread state. (Like all
other Python/C API functions, the global interpreter lock must be held before
calling this function and is still held when it returns; however, unlike most
other Python/C API functions, there needn’t be a current thread state on
entry.)</p>
<p>Extension modules are shared between (sub-)interpreters as follows: the first
time a particular extension is imported, it is initialized normally, and a
(shallow) copy of its module’s dictionary is squirreled away. When the same
extension is imported by another (sub-)interpreter, a new module is initialized
and filled with the contents of this copy; the extension’s function is
not called. Note that this is different from what happens when an extension is
imported after the interpreter has been completely re-initialized by calling
<a href="#Py_Finalize"></a> and <a href="#Py_Initialize"></a>; in that case, the extension’s
 function <em>is</em> called again.</p>
</dd></dl>
<dl>
<dt>
void <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#Py_EndInterpreter">¶</a></dt>
<dd><p>Destroy the (sub-)interpreter represented by the given thread state. The given
thread state must be the current thread state. See the discussion of thread
states below. When the call returns, the current thread state is <em>NULL</em>. All
thread states associated with this interpreter are destroyed. (The global
interpreter lock must be held before calling this function and is still held
when it returns.) <a href="#Py_Finalize"></a> will destroy all sub-interpreters that
haven’t been explicitly destroyed at that point.</p>
</dd></dl>
<div>
<h3>Bugs and caveats<a href="#bugs-and-caveats">¶</a></h3>
<p>Because sub-interpreters (and the main interpreter) are part of the same
process, the insulation between them isn’t perfect — for example, using
low-level file operations like <a href="https://docs.python.org/3.3/library/os.html#os.close"></a> they can
(accidentally or maliciously) affect each other’s open files. Because of the
way extensions are shared between (sub-)interpreters, some extensions may not
work properly; this is especially likely when the extension makes use of
(static) global variables, or when the extension manipulates its module’s
dictionary after its initialization. It is possible to insert objects created
in one sub-interpreter into a namespace of another sub-interpreter; this should
be done with great care to avoid sharing user-defined functions, methods,
instances or classes between sub-interpreters, since import operations executed
by such objects may affect the wrong (sub-)interpreter’s dictionary of loaded
modules.</p>
<p>Also note that combining this functionality with APIs
is delicate, because these APIs assume a bijection between Python thread states
and OS-level threads, an assumption broken by the presence of sub-interpreters.
It is highly recommended that you don’t switch sub-interpreters between a pair
of matching <a href="#PyGILState_Ensure"></a> and <a href="#PyGILState_Release"></a> calls.
Furthermore, extensions (such as <a href="https://docs.python.org/3.3/library/ctypes.html#module-ctypes"></a>) using these APIs to allow calling
of Python code from non-Python created threads will probably be broken when using
sub-interpreters.</p>
</div>
</div>
<div>
<h2>Asynchronous Notifications<a href="#asynchronous-notifications">¶</a></h2>
<p>A mechanism is provided to make asynchronous notifications to the main
interpreter thread. These notifications take the form of a function
pointer and a void pointer argument.</p>
<dl>
<dt>
int int (*func)(void<em> *)</em>, void<em> *arg</em><a href="#Py_AddPendingCall">¶</a></dt>
<dd><p>Schedule a function to be called from the main interpreter thread. On
success, 0 is returned and <em>func</em> is queued for being called in the
main thread. On failure, -1 is returned without setting any exception.</p>
<p>When successfully queued, <em>func</em> will be <em>eventually</em> called from the
main interpreter thread with the argument <em>arg</em>. It will be called
asynchronously with respect to normally running Python code, but with
both these conditions met:</p>
<ul>
<li>on a <a href="https://docs.python.org/3.3/glossary.html#term-bytecode"><em>bytecode</em></a> boundary;</li>
<li>with the main thread holding the <a href="https://docs.python.org/3.3/glossary.html#term-global-interpreter-lock"><em>global interpreter lock</em></a>
(<em>func</em> can therefore use the full C API).</li>
</ul>
<p><em>func</em> must return 0 on success, or -1 on failure with an exception
set. <em>func</em> won’t be interrupted to perform another asynchronous
notification recursively, but it can still be interrupted to switch
threads if the global interpreter lock is released.</p>
<p>This function doesn’t need a current thread state to run, and it doesn’t
need the global interpreter lock.</p>
<div>
<p>Warning</p>
<p>This is a low-level function, only useful for very special cases.
There is no guarantee that <em>func</em> will be called as quick as
possible. If the main thread is busy executing a system call,
<em>func</em> won’t be called before the system call returns. This
function is generally <strong>not</strong> suitable for calling Python code from
arbitrary C threads. Instead, use the <a href="#gilstate"><em>PyGILState API</em></a>.</p>
</div>
<p></p>
</dd></dl>
</div>
<div>
<h2>Profiling and Tracing<a href="#profiling-and-tracing">¶</a></h2>
<p>The Python interpreter provides some low-level support for attaching profiling
and execution tracing facilities. These are used for profiling, debugging, and
coverage analysis tools.</p>
<p>This C interface allows the profiling or tracing code to avoid the overhead of
calling through Python-level callable objects, making a direct C function call
instead. The essential attributes of the facility have not changed; the
interface allows trace functions to be installed per-thread, and the basic
events reported to the trace function are the same as had been reported to the
Python-level trace functions in previous versions.</p>
<dl>
<dt>
int <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *obj</em>, PyFrameObject<em> *frame</em>, int<em> what</em>, <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *arg</em><a href="#Py_tracefunc">¶</a></dt>
<dd><p>The type of the trace function registered using <a href="#PyEval_SetProfile"></a> and
<a href="#PyEval_SetTrace"></a>. The first parameter is the object passed to the
registration function as <em>obj</em>, <em>frame</em> is the frame object to which the event
pertains, <em>what</em> is one of the constants ,
, , ,
, , or
, and <em>arg</em> depends on the value of <em>what</em>:</p>
<table>
<colgroup>
<col/>
<col/>
</colgroup>
<thead>
<tr><th>Value of <em>what</em></th>
<th>Meaning of <em>arg</em></th>
</tr>
</thead>
<tbody>
<tr><td></td>
<td>Always <em>NULL</em>.</td>
</tr>
<tr><td></td>
<td>Exception information as returned by
<a href="https://docs.python.org/3.3/library/sys.html#sys.exc_info"></a>.</td>
</tr>
<tr><td></td>
<td>Always <em>NULL</em>.</td>
</tr>
<tr><td></td>
<td>Value being returned to the caller,
or <em>NULL</em> if caused by an exception.</td>
</tr>
<tr><td></td>
<td>Function object being called.</td>
</tr>
<tr><td></td>
<td>Function object being called.</td>
</tr>
<tr><td></td>
<td>Function object being called.</td>
</tr>
</tbody>
</table>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_CALL">¶</a></dt>
<dd><p>The value of the <em>what</em> parameter to a <a href="#Py_tracefunc"></a> function when a new
call to a function or method is being reported, or a new entry into a generator.
Note that the creation of the iterator for a generator function is not reported
as there is no control transfer to the Python bytecode in the corresponding
frame.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_EXCEPTION">¶</a></dt>
<dd><p>The value of the <em>what</em> parameter to a <a href="#Py_tracefunc"></a> function when an
exception has been raised. The callback function is called with this value for
<em>what</em> when after any bytecode is processed after which the exception becomes
set within the frame being executed. The effect of this is that as exception
propagation causes the Python stack to unwind, the callback is called upon
return to each frame as the exception propagates. Only trace functions receives
these events; they are not needed by the profiler.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_LINE">¶</a></dt>
<dd><p>The value passed as the <em>what</em> parameter to a trace function (but not a
profiling function) when a line-number event is being reported.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_RETURN">¶</a></dt>
<dd><p>The value for the <em>what</em> parameter to <a href="#Py_tracefunc"></a> functions when a
call is returning without propagating an exception.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_C_CALL">¶</a></dt>
<dd><p>The value for the <em>what</em> parameter to <a href="#Py_tracefunc"></a> functions when a C
function is about to be called.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_C_EXCEPTION">¶</a></dt>
<dd><p>The value for the <em>what</em> parameter to <a href="#Py_tracefunc"></a> functions when a C
function has raised an exception.</p>
</dd></dl>
<dl>
<dt>
int <a href="#PyTrace_C_RETURN">¶</a></dt>
<dd><p>The value for the <em>what</em> parameter to <a href="#Py_tracefunc"></a> functions when a C
function has returned.</p>
</dd></dl>
<dl>
<dt>
void <a href="#Py_tracefunc">Py_tracefunc</a><em> func</em>, <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *obj</em><a href="#PyEval_SetProfile">¶</a></dt>
<dd><p>Set the profiler function to <em>func</em>. The <em>obj</em> parameter is passed to the
function as its first parameter, and may be any Python object, or <em>NULL</em>. If
the profile function needs to maintain state, using a different value for <em>obj</em>
for each thread provides a convenient and thread-safe place to store it. The
profile function is called for all monitored events except the line-number
events.</p>
</dd></dl>
<dl>
<dt>
void <a href="#Py_tracefunc">Py_tracefunc</a><em> func</em>, <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *obj</em><a href="#PyEval_SetTrace">¶</a></dt>
<dd><p>Set the tracing function to <em>func</em>. This is similar to
<a href="#PyEval_SetProfile"></a>, except the tracing function does receive line-number
events.</p>
</dd></dl>
<dl>
<dt>
<a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a>* <a href="https://docs.python.org/3.3/c-api/structures.html#PyObject">PyObject</a><em> *self</em><a href="#PyEval_GetCallStats">¶</a></dt>
<dd><p>Return a tuple of function call counts. There are constants defined for the
positions within the tuple:</p>
<table>
<colgroup>
<col/>
<col/>
</colgroup>
<thead>
<tr><th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr><td></td>
<td>0</td>
</tr>
<tr><td></td>
<td>1</td>
</tr>
<tr><td></td>
<td>2</td>
</tr>
<tr><td></td>
<td>3</td>
</tr>
<tr><td></td>
<td>4</td>
</tr>
<tr><td></td>
<td>5</td>
</tr>
<tr><td></td>
<td>6</td>
</tr>
<tr><td></td>
<td>7</td>
</tr>
<tr><td></td>
<td>8</td>
</tr>
<tr><td></td>
<td>9</td>
</tr>
<tr><td></td>
<td>10</td>
</tr>
</tbody>
</table>
<p> means no argument tuple needs to be created.
 means that the fast-path frame setup code is used.</p>
<p>If there is a method call where the call can be optimized by changing
the argument tuple and calling the function directly, it gets recorded
twice.</p>
<p>This function is only present if Python is compiled with 
defined.</p>
</dd></dl>
</div>
<div>
<h2>Advanced Debugger Support<a href="#advanced-debugger-support">¶</a></h2>
<p>These functions are only intended to be used by advanced debugging tools.</p>
<dl>
<dt>
<a href="#PyInterpreterState">PyInterpreterState</a>* <a href="#PyInterpreterState_Head">¶</a></dt>
<dd><p>Return the interpreter state object at the head of the list of all such objects.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyInterpreterState">PyInterpreterState</a>* <a href="#PyInterpreterState">PyInterpreterState</a><em> *interp</em><a href="#PyInterpreterState_Next">¶</a></dt>
<dd><p>Return the next interpreter state object after <em>interp</em> from the list of all
such objects.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a> * <a href="#PyInterpreterState">PyInterpreterState</a><em> *interp</em><a href="#PyInterpreterState_ThreadHead">¶</a></dt>
<dd><p>Return the a pointer to the first <a href="#PyThreadState"></a> object in the list of
threads associated with the interpreter <em>interp</em>.</p>
</dd></dl>
<dl>
<dt>
<a href="#PyThreadState">PyThreadState</a>* <a href="#PyThreadState">PyThreadState</a><em> *tstate</em><a href="#PyThreadState_Next">¶</a></dt>
<dd><p>Return the next thread state object after <em>tstate</em> from the list of all such
objects belonging to the same <a href="#PyInterpreterState"></a> object.</p>
</dd></dl>
</div>
</div></div>||||I|||| Navigation

 * index
 * modules |
 * next |
 * previous |
 * 
 * Python »
 * 3.3.7 Documentation »
 * Python/C API Reference Manual »

 Initialization, Finalization, and Threads¶

 Initializing and finalizing the interpreter¶

 void Py_Initialize()¶

 Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the exception of Py_SetProgramName() , Py_SetPythonHome() and Py_SetPath() . This initializes the table of loaded modules ( sys.modules ), and creates the fundamental modules builtins , __main__ and sys . It also initializes the module search path ( sys.path ). It does not set sys.argv ; use PySys_SetArgvEx() for that. This is a no-op when called for a second time (without calling Py_Finalize() first). There is no return value; it is a fatal error if the initialization fails.

 void Py_InitializeEx(int initsigs)¶

 This function works like Py_Initialize() if initsigs is 1. If initsigs is 0, it skips initialization registration of signal handlers, which might be useful when Python is embedded.

 int Py_IsInitialized()¶

 Return true (nonzero) when the Python interpreter has been initialized, false (zero) if not. After Py_Finalize() is called, this returns false until Py_Initialize() is called again.

 void Py_Finalize()¶

 Undo all initializations made by Py_Initialize() and subsequent use of Python/C API functions, and destroy all sub-interpreters (see Py_NewInterpreter() below) that were created and not yet destroyed since the last call to Py_Initialize() . Ideally, this frees all memory allocated by the Python interpreter. This is a no-op when called for a second time (without calling Py_Initialize() again first). There is no return value; errors during finalization are ignored.

 This function is provided for a number of reasons. An embedding application might want to restart Python without having to restart the application itself. An application that has loaded the Python interpreter from a dynamically loadable library (or DLL) might want to free all memory allocated by Python before unloading the DLL. During a hunt for memory leaks in an application a developer might want to free all memory allocated by Python before exiting from the application.

 Bugs and caveats: The destruction of modules and objects in modules is done in random order; this may cause destructors ( __del__() methods) to fail when they depend on other objects (even functions) or modules. Dynamically loaded extension modules loaded by Python are not unloaded. Small amounts of memory allocated by the Python interpreter may not be freed (if you find a leak, please report it). Memory tied up in circular references between objects is not freed. Some memory allocated by extension modules may not be freed. Some extensions may not work properly if their initialization routine is called more than once; this can happen if an application calls Py_Initialize() and Py_Finalize() more than once.

 Process-wide parameters¶

 void Py_SetProgramName(wchar_t *name)¶

 This function should be called before Py_Initialize() is called for the first time, if it is called at all. It tells the interpreter the value of the argv[0] argument to the main() function of the program (converted to wide characters). This is used by Py_GetPath() and some other functions below to find the Python run-time libraries relative to the interpreter executable. The default value is 'python' . The argument should point to a zero-terminated wide character string in static storage whose contents will not change for the duration of the program’s execution. No code in the Python interpreter will change the contents of this storage.

 wchar* Py_GetProgramName()¶

 Return the program name set with Py_SetProgramName() , or the default. The returned string points into static storage; the caller should not modify its value.

 wchar_t* Py_GetPrefix()¶

 Return the prefix for installed platform-independent files. This is derived through a number of complicated rules from the program name set with Py_SetProgramName() and some environment variables; for example, if the program name is '/usr/local/bin/python' , the prefix is '/usr/local' . The returned string points into static storage; the caller should not modify its value. This corresponds to the prefix variable in the top-level Makefile and the --prefix argument to the configure script at build time. The value is available to Python code as sys.prefix . It is only useful on Unix. See also the next function.

 wchar_t* Py_GetExecPrefix()¶

 Return the exec-prefix for installed platform-dependent files. This is derived through a number of complicated rules from the program name set with Py_SetProgramName() and some environment variables; for example, if the program name is '/usr/local/bin/python' , the exec-prefix is '/usr/local' . The returned string points into static storage; the caller should not modify its value. This corresponds to the exec_prefix variable in the top-level Makefile and the --exec-prefix argument to the configure script at build time. The value is available to Python code as sys.exec_prefix . It is only useful on Unix.

 Background: The exec-prefix differs from the prefix when platform dependent files (such as executables and shared libraries) are installed in a different directory tree. In a typical installation, platform dependent files may be installed in the /usr/local/plat subtree while platform independent may be installed in /usr/local .

 Generally speaking, a platform is a combination of hardware and software families, e.g. Sparc machines running the Solaris 2.x operating system are considered the same platform, but Intel machines running Solaris 2.x are another platform, and Intel machines running Linux are yet another platform. Different major revisions of the same operating system generally also form different platforms. Non-Unix operating systems are a different story; the installation strategies on those systems are so different that the prefix and exec-prefix are meaningless, and set to the empty string. Note that compiled Python bytecode files are platform independent (but not independent from the Python version by which they were compiled!).

 System administrators will know how to configure the mount or automount programs to share /usr/local between platforms while having /usr/local/plat be a different filesystem for each platform.

 wchar_t* Py_GetProgramFullPath()¶

 Return the full program name of the Python executable; this is computed as a side-effect of deriving the default module search path from the program name (set by Py_SetProgramName() above). The returned string points into static storage; the caller should not modify its value. The value is available to Python code as sys.executable .

 wchar_t* Py_GetPath()¶

 Return the default module search path; this is computed from the program name (set by Py_SetProgramName() above) and some environment variables. The returned string consists of a series of directory names separated by a platform dependent delimiter character. The delimiter character is ':' on Unix and Mac OS X, ';' on Windows. The returned string points into static storage; the caller should not modify its value. The list sys.path is initialized with this value on interpreter startup; it can be (and usually is) modified later to change the search path for loading modules.

 void Py_SetPath(const wchar_t *)¶

 Set the default module search path. If this function is called before Py_Initialize() , then Py_GetPath() won’t attempt to compute a default search path but uses the one provided instead. This is useful if Python is embedded by an application that has full knowledge of the location of all modules. The path components should be separated by semicolons.

 This also causes sys.executable to be set only to the raw program name (see Py_SetProgramName() ) and for sys.prefix and sys.exec_prefix to be empty. It is up to the caller to modify these if required after calling Py_Initialize() .

 const char* Py_GetVersion()¶

 Return the version of this Python interpreter. This is a string that looks something like

 "3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"
 

 The first word (up to the first space character) is the current Python version; the first three characters are the major and minor version separated by a period. The returned string points into static storage; the caller should not modify its value. The value is available to Python code as sys.version .

 const char* Py_GetPlatform()¶

 Return the platform identifier for the current platform. On Unix, this is formed from the “official” name of the operating system, converted to lower case, followed by the major revision number; e.g., for Solaris 2.x, which is also known as SunOS 5.x, the value is 'sunos5' . On Mac OS X, it is 'darwin' . On Windows, it is 'win' . The returned string points into static storage; the caller should not modify its value. The value is available to Python code as sys.platform .

 const char* Py_GetCopyright()¶

 Return the official copyright string for the current Python version, for example

 'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'

 The returned string points into static storage; the caller should not modify its value. The value is available to Python code as sys.copyright .

 const char* Py_GetCompiler()¶

 Return an indication of the compiler used to build the current Python version, in square brackets, for example:

 "[GCC 2.7.2.2]"
 

 The returned string points into static storage; the caller should not modify its value. The value is available to Python code as part of the variable sys.version .

 const char* Py_GetBuildInfo()¶

 Return information about the sequence number and build date and time of the current Python interpreter instance, for example

 "#67, Aug 1 1997, 22:34:28"
 

 The returned string points into static storage; the caller should not modify its value. The value is available to Python code as part of the variable sys.version .

 void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)¶

 Set sys.argv based on argc and argv. These parameters are similar to those passed to the program’s main() function with the difference that the first entry should refer to the script file to be executed rather than the executable hosting the Python interpreter. If there isn’t a script that will be run, the first entry in argv can be an empty string. If this function fails to initialize sys.argv , a fatal condition is signalled using Py_FatalError() .

 If updatepath is zero, this is all the function does. If updatepath is non-zero, the function also modifies sys.path according to the following algorithm:

 * If the name of an existing script is passed in argv[0] , the absolute path of the directory where the script is located is prepended to sys.path .
 * Otherwise (that is, if argc is 0 or argv[0] doesn’t point to an existing file name), an empty string is prepended to sys.path , which is the same as prepending the current working directory ( "." ).

 Note

 It is recommended that applications embedding the Python interpreter for purposes other than executing a single script pass 0 as updatepath, and update sys.path themselves if desired. See CVE-2008-5983.

 On versions before 3.1.3, you can achieve the same effect by manually popping the first sys.path element after having called PySys_SetArgv() , for example using:

 PyRun_SimpleString("import sys; sys.path.pop(0)\n");
 

 New in version 3.1.3.

 void PySys_SetArgv(int argc, wchar_t **argv)¶

 This function works like PySys_SetArgvEx() with updatepath set to 1.

 void Py_SetPythonHome(wchar_t *home)¶

 Set the default “home” directory, that is, the location of the standard Python libraries. See PYTHONHOME for the meaning of the argument string.

 The argument should point to a zero-terminated character string in static storage whose contents will not change for the duration of the program’s execution. No code in the Python interpreter will change the contents of this storage.

 w_char* Py_GetPythonHome()¶

 Return the default “home”, that is, the value set by a previous call to Py_SetPythonHome() , or the value of the PYTHONHOME environment variable if it is set.

 Thread State and the Global Interpreter Lock¶

 The Python interpreter is not fully thread-safe. In order to support multi-threaded Python programs, there’s a global lock, called the global interpreter lock or GIL, that must be held by the current thread before it can safely access Python objects. Without the lock, even the simplest operations could cause problems in a multi-threaded program: for example, when two threads simultaneously increment the reference count of the same object, the reference count could end up being incremented only once instead of twice.

 Therefore, the rule exists that only the thread that has acquired the GIL may operate on Python objects or call Python/C API functions. In order to emulate concurrency of execution, the interpreter regularly tries to switch threads (see sys.setswitchinterval() ). The lock is also released around potentially blocking I/O operations like reading or writing a file, so that other Python threads can run in the meantime.

 The Python interpreter keeps some thread-specific bookkeeping information inside a data structure called PyThreadState . There’s also one global variable pointing to the current PyThreadState : it can be retrieved using PyThreadState_Get() .

 Releasing the GIL from extension code¶

 Most extension code manipulating the GIL has the following simple structure:

 Save the thread state in a local variable.
 Release the global interpreter lock.
 ... Do some blocking I/O operation ...
 Reacquire the global interpreter lock.
 Restore the thread state from the local variable.
 

 This is so common that a pair of macros exists to simplify it:

 Py_BEGIN_ALLOW_THREADS
 ... Do some blocking I/O operation ...
 Py_END_ALLOW_THREADS
 

 The Py_BEGIN_ALLOW_THREADS macro opens a new block and declares a hidden local variable; the Py_END_ALLOW_THREADS macro closes the block. These two macros are still available when Python is compiled without thread support (they simply have an empty expansion).

 When thread support is enabled, the block above expands to the following code:

 PyThreadState *_save;
 
 _save = PyEval_SaveThread();
 ...Do some blocking I/O operation...
 PyEval_RestoreThread(_save);
 

 Here is how these functions work: the global interpreter lock is used to protect the pointer to the current thread state. When releasing the lock and saving the thread state, the current thread state pointer must be retrieved before the lock is released (since another thread could immediately acquire the lock and store its own thread state in the global variable). Conversely, when acquiring the lock and restoring the thread state, the lock must be acquired before storing the thread state pointer.

 Note

 Calling system I/O functions is the most common use case for releasing the GIL, but it can also be useful before calling long-running computations which don’t need access to Python objects, such as compression or cryptographic functions operating over memory buffers. For example, the standard zlib and hashlib modules release the GIL when compressing or hashing data.

 Non-Python created threads¶

 When threads are created using the dedicated Python APIs (such as the threading module), a thread state is automatically associated to them and the code showed above is therefore correct. However, when threads are created from C (for example by a third-party library with its own thread management), they don’t hold the GIL, nor is there a thread state structure for them.

 If you need to call Python code from these threads (often this will be part of a callback API provided by the aforementioned third-party library), you must first register these threads with the interpreter by creating a thread state data structure, then acquiring the GIL, and finally storing their thread state pointer, before you can start using the Python/C API. When you are done, you should reset the thread state pointer, release the GIL, and finally free the thread state data structure.

 The PyGILState_Ensure() and PyGILState_Release() functions do all of the above automatically. The typical idiom for calling into Python from a C thread is:

 PyGILState_STATE gstate;
 gstate = PyGILState_Ensure();
 
 /* Perform Python actions here. */
 result = CallSomeFunction();
 /* evaluate result or handle exception */
 
 /* Release the thread. No Python API allowed beyond this point. */
 PyGILState_Release(gstate);
 

 Note that the PyGILState_*() functions assume there is only one global interpreter (created automatically by Py_Initialize() ). Python supports the creation of additional interpreters (using Py_NewInterpreter() ), but mixing multiple interpreters and the PyGILState_*() API is unsupported.

 Another important thing to note about threads is their behaviour in the face of the C fork() call. On most systems with fork() , after a process forks only the thread that issued the fork will exist. That also means any locks held by other threads will never be released. Python solves this for os.fork() by acquiring the locks it uses internally before the fork, and releasing them afterwards. In addition, it resets any Lock Objects in the child. When extending or embedding Python, there is no way to inform Python of additional (non-Python) locks that need to be acquired before or reset after a fork. OS facilities such as pthread_atfork() would need to be used to accomplish the same thing. Additionally, when extending or embedding Python, calling fork() directly rather than through os.fork() (and returning to or calling into Python) may result in a deadlock by one of Python’s internal locks being held by a thread that is defunct after the fork. PyOS_AfterFork() tries to reset the necessary locks, but is not always able to.

 High-level API¶

 These are the most commonly used types and functions when writing C extension code, or when embedding the Python interpreter:

 PyInterpreterState¶

 This data structure represents the state shared by a number of cooperating threads. Threads belonging to the same interpreter share their module administration and a few other internal items. There are no public members in this structure.

 Threads belonging to different interpreters initially share nothing, except process state like available memory, open file descriptors and such. The global interpreter lock is also shared by all threads, regardless of to which interpreter they belong.

 PyThreadState¶

 This data structure represents the state of a single thread. The only public data member is PyInterpreterState * interp , which points to this thread’s interpreter state.

 void PyEval_InitThreads()¶

 Initialize and acquire the global interpreter lock. It should be called in the main thread before creating a second thread or engaging in any other thread operations such as PyEval_ReleaseThread(tstate) . It is not needed before calling PyEval_SaveThread() or PyEval_RestoreThread() .

 This is a no-op when called for a second time.

 Changed in version 3.2: This function cannot be called before Py_Initialize() anymore.

 Note

 When only the main thread exists, no GIL operations are needed. This is a common situation (most Python programs do not use threads), and the lock operations slow the interpreter down a bit. Therefore, the lock is not created initially. This situation is equivalent to having acquired the lock: when there is only a single thread, all object accesses are safe. Therefore, when this function initializes the global interpreter lock, it also acquires it. Before the Python _thread module creates a new thread, knowing that either it has the lock or the lock hasn’t been created yet, it calls PyEval_InitThreads() . When this call returns, it is guaranteed that the lock has been created and that the calling thread has acquired it.

 It is not safe to call this function when it is unknown which thread (if any) currently has the global interpreter lock.

 This function is not available when thread support is disabled at compile time.

 int PyEval_ThreadsInitialized()¶

 Returns a non-zero value if PyEval_InitThreads() has been called. This function can be called without holding the GIL, and therefore can be used to avoid calls to the locking API when running single-threaded. This function is not available when thread support is disabled at compile time.

 PyThreadState* PyEval_SaveThread()¶

 Release the global interpreter lock (if it has been created and thread support is enabled) and reset the thread state to NULL, returning the previous thread state (which is not NULL). If the lock has been created, the current thread must have acquired it. (This function is available even when thread support is disabled at compile time.)

 void PyEval_RestoreThread(PyThreadState *tstate)¶

 Acquire the global interpreter lock (if it has been created and thread support is enabled) and set the thread state to tstate, which must not be NULL. If the lock has been created, the current thread must not have acquired it, otherwise deadlock ensues. (This function is available even when thread support is disabled at compile time.)

 PyThreadState* PyThreadState_Get()¶

 Return the current thread state. The global interpreter lock must be held. When the current thread state is NULL, this issues a fatal error (so that the caller needn’t check for NULL).

 PyThreadState* PyThreadState_Swap(PyThreadState *tstate)¶

 Swap the current thread state with the thread state given by the argument tstate, which may be NULL. The global interpreter lock must be held and is not released.

 void PyEval_ReInitThreads()¶

 This function is called from PyOS_AfterFork() to ensure that newly created child processes don’t hold locks referring to threads which are not running in the child process.

 The following functions use thread-local storage, and are not compatible with sub-interpreters:

 PyGILState_STATE PyGILState_Ensure()¶

 Ensure that the current thread is ready to call the Python C API regardless of the current state of Python, or of the global interpreter lock. This may be called as many times as desired by a thread as long as each call is matched with a call to PyGILState_Release() . In general, other thread-related APIs may be used between PyGILState_Ensure() and PyGILState_Release() calls as long as the thread state is restored to its previous state before the Release(). For example, normal usage of the Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros is acceptable.

 The return value is an opaque “handle” to the thread state when PyGILState_Ensure() was called, and must be passed to PyGILState_Release() to ensure Python is left in the same state. Even though recursive calls are allowed, these handles cannot be shared - each unique call to PyGILState_Ensure() must save the handle for its call to PyGILState_Release() .

 When the function returns, the current thread will hold the GIL and be able to call arbitrary Python code. Failure is a fatal error.

 void PyGILState_Release(PyGILState_STATE)¶

 Release any resources previously acquired. After this call, Python’s state will be the same as it was prior to the corresponding PyGILState_Ensure() call (but generally this state will be unknown to the caller, hence the use of the GILState API).

 Every call to PyGILState_Ensure() must be matched by a call to PyGILState_Release() on the same thread.

 PyThreadState* PyGILState_GetThisThreadState()¶

 Get the current thread state for this thread. May return NULL if no GILState API has been used on the current thread. Note that the main thread always has such a thread-state, even if no auto-thread-state call has been made on the main thread. This is mainly a helper/diagnostic function.

 The following macros are normally used without a trailing semicolon; look for example usage in the Python source distribution.

 Py_BEGIN_ALLOW_THREADS¶

 This macro expands to { PyThreadState *_save; _save = PyEval_SaveThread(); . Note that it contains an opening brace; it must be matched with a following Py_END_ALLOW_THREADS macro. See above for further discussion of this macro. It is a no-op when thread support is disabled at compile time.

 Py_END_ALLOW_THREADS¶

 This macro expands to PyEval_RestoreThread(_save); } . Note that it contains a closing brace; it must be matched with an earlier Py_BEGIN_ALLOW_THREADS macro. See above for further discussion of this macro. It is a no-op when thread support is disabled at compile time.

 Py_BLOCK_THREADS¶

 This macro expands to PyEval_RestoreThread(_save); : it is equivalent to Py_END_ALLOW_THREADS without the closing brace. It is a no-op when thread support is disabled at compile time.

 Py_UNBLOCK_THREADS¶

 This macro expands to _save = PyEval_SaveThread(); : it is equivalent to Py_BEGIN_ALLOW_THREADS without the opening brace and variable declaration. It is a no-op when thread support is disabled at compile time.

 Low-level API¶

 All of the following functions are only available when thread support is enabled at compile time, and must be called only when the global interpreter lock has been created.

 PyInterpreterState* PyInterpreterState_New()¶

 Create a new interpreter state object. The global interpreter lock need not be held, but may be held if it is necessary to serialize calls to this function.

 void PyInterpreterState_Clear(PyInterpreterState *interp)¶

 Reset all information in an interpreter state object. The global interpreter lock must be held.

 void PyInterpreterState_Delete(PyInterpreterState *interp)¶

 Destroy an interpreter state object. The global interpreter lock need not be held. The interpreter state must have been reset with a previous call to PyInterpreterState_Clear() .

 PyThreadState* PyThreadState_New(PyInterpreterState *interp)¶

 Create a new thread state object belonging to the given interpreter object. The global interpreter lock need not be held, but may be held if it is necessary to serialize calls to this function.

 void PyThreadState_Clear(PyThreadState *tstate)¶

 Reset all information in a thread state object. The global interpreter lock must be held.

 void PyThreadState_Delete(PyThreadState *tstate)¶

 Destroy a thread state object. The global interpreter lock need not be held. The thread state must have been reset with a previous call to PyThreadState_Clear() .

 PyObject* PyThreadState_GetDict()¶ Return value: Borrowed reference.

 Return a dictionary in which extensions can store thread-specific state information. Each extension should use a unique key to use to store state in the dictionary. It is okay to call this function when no current thread state is available. If this function returns NULL, no exception has been raised and the caller should assume no current thread state is available.

 int PyThreadState_SetAsyncExc(long id, PyObject *exc)¶

 Asynchronously raise an exception in a thread. The id argument is the thread id of the target thread; exc is the exception object to be raised. This function does not steal any references to exc. To prevent naive misuse, you must write your own C extension to call this. Must be called with the GIL held. Returns the number of thread states modified; this is normally one, but will be zero if the thread id isn’t found. If exc is NULL , the pending exception (if any) for the thread is cleared. This raises no exceptions.

 void PyEval_AcquireThread(PyThreadState *tstate)¶

 Acquire the global interpreter lock and set the current thread state to tstate, which should not be NULL. The lock must have been created earlier. If this thread already has the lock, deadlock ensues.

 PyEval_RestoreThread() is a higher-level function which is always available (even when thread support isn’t enabled or when threads have not been initialized).

 void PyEval_ReleaseThread(PyThreadState *tstate)¶

 Reset the current thread state to NULL and release the global interpreter lock. The lock must have been created earlier and must be held by the current thread. The tstate argument, which must not be NULL, is only used to check that it represents the current thread state — if it isn’t, a fatal error is reported.

 PyEval_SaveThread() is a higher-level function which is always available (even when thread support isn’t enabled or when threads have not been initialized).

 void PyEval_AcquireLock()¶

 Acquire the global interpreter lock. The lock must have been created earlier. If this thread already has the lock, a deadlock ensues.

 Deprecated since version 3.2: This function does not update the current thread state. Please use PyEval_RestoreThread() or PyEval_AcquireThread() instead.

 void PyEval_ReleaseLock()¶

 Release the global interpreter lock. The lock must have been created earlier.

 Deprecated since version 3.2: This function does not update the current thread state. Please use PyEval_SaveThread() or PyEval_ReleaseThread() instead.

 Sub-interpreter support¶

 While in most uses, you will only embed a single Python interpreter, there are cases where you need to create several independent interpreters in the same process and perhaps even in the same thread. Sub-interpreters allow you to do that. You can switch between sub-interpreters using the PyThreadState_Swap() function. You can create and destroy them using the following functions:

 PyThreadState* Py_NewInterpreter()¶

 Create a new sub-interpreter. This is an (almost) totally separate environment for the execution of Python code. In particular, the new interpreter has separate, independent versions of all imported modules, including the fundamental modules builtins , __main__ and sys . The table of loaded modules ( sys.modules ) and the module search path ( sys.path ) are also separate. The new environment has no sys.argv variable. It has new standard I/O stream file objects sys.stdin , sys.stdout and sys.stderr (however these refer to the same underlying file descriptors).

 The return value points to the first thread state created in the new sub-interpreter. This thread state is made in the current thread state. Note that no actual thread is created; see the discussion of thread states below. If creation of the new interpreter is unsuccessful, NULL is returned; no exception is set since the exception state is stored in the current thread state and there may not be a current thread state. (Like all other Python/C API functions, the global interpreter lock must be held before calling this function and is still held when it returns; however, unlike most other Python/C API functions, there needn’t be a current thread state on entry.)

 Extension modules are shared between (sub-)interpreters as follows: the first time a particular extension is imported, it is initialized normally, and a (shallow) copy of its module’s dictionary is squirreled away. When the same extension is imported by another (sub-)interpreter, a new module is initialized and filled with the contents of this copy; the extension’s init function is not called. Note that this is different from what happens when an extension is imported after the interpreter has been completely re-initialized by calling Py_Finalize() and Py_Initialize() ; in that case, the extension’s initmodule function is called again.

 void Py_EndInterpreter(PyThreadState *tstate)¶

 Destroy the (sub-)interpreter represented by the given thread state. The given thread state must be the current thread state. See the discussion of thread states below. When the call returns, the current thread state is NULL. All thread states associated with this interpreter are destroyed. (The global interpreter lock must be held before calling this function and is still held when it returns.) Py_Finalize() will destroy all sub-interpreters that haven’t been explicitly destroyed at that point.

 Bugs and caveats¶

 Because sub-interpreters (and the main interpreter) are part of the same process, the insulation between them isn’t perfect — for example, using low-level file operations like os.close() they can (accidentally or maliciously) affect each other’s open files. Because of the way extensions are shared between (sub-)interpreters, some extensions may not work properly; this is especially likely when the extension makes use of (static) global variables, or when the extension manipulates its module’s dictionary after its initialization. It is possible to insert objects created in one sub-interpreter into a namespace of another sub-interpreter; this should be done with great care to avoid sharing user-defined functions, methods, instances or classes between sub-interpreters, since import operations executed by such objects may affect the wrong (sub-)interpreter’s dictionary of loaded modules.

 Also note that combining this functionality with PyGILState_*() APIs is delicate, because these APIs assume a bijection between Python thread states and OS-level threads, an assumption broken by the presence of sub-interpreters. It is highly recommended that you don’t switch sub-interpreters between a pair of matching PyGILState_Ensure() and PyGILState_Release() calls. Furthermore, extensions (such as ctypes ) using these APIs to allow calling of Python code from non-Python created threads will probably be broken when using sub-interpreters.

 Asynchronous Notifications¶

 A mechanism is provided to make asynchronous notifications to the main interpreter thread. These notifications take the form of a function pointer and a void pointer argument.

 int Py_AddPendingCall(int (*func)(void *), void *arg)¶

 Schedule a function to be called from the main interpreter thread. On success, 0 is returned and func is queued for being called in the main thread. On failure, -1 is returned without setting any exception.

 When successfully queued, func will be eventually called from the main interpreter thread with the argument arg. It will be called asynchronously with respect to normally running Python code, but with both these conditions met:

 * on a bytecode boundary;
 * with the main thread holding the global interpreter lock (func can therefore use the full C API).

 func must return 0 on success, or -1 on failure with an exception set. func won’t be interrupted to perform another asynchronous notification recursively, but it can still be interrupted to switch threads if the global interpreter lock is released.

 This function doesn’t need a current thread state to run, and it doesn’t need the global interpreter lock.

 Warning

 This is a low-level function, only useful for very special cases. There is no guarantee that func will be called as quick as possible. If the main thread is busy executing a system call, func won’t be called before the system call returns. This function is generally not suitable for calling Python code from arbitrary C threads. Instead, use the PyGILState API.

 New in version 3.1.

 Profiling and Tracing¶

 The Python interpreter provides some low-level support for attaching profiling and execution tracing facilities. These are used for profiling, debugging, and coverage analysis tools.

 This C interface allows the profiling or tracing code to avoid the overhead of calling through Python-level callable objects, making a direct C function call instead. The essential attributes of the facility have not changed; the interface allows trace functions to be installed per-thread, and the basic events reported to the trace function are the same as had been reported to the Python-level trace functions in previous versions.

 int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)¶

 The type of the trace function registered using PyEval_SetProfile() and PyEval_SetTrace() . The first parameter is the object passed to the registration function as obj, frame is the frame object to which the event pertains, what is one of the constants PyTrace_CALL , PyTrace_EXCEPTION , PyTrace_LINE , PyTrace_RETURN , PyTrace_C_CALL , PyTrace_C_EXCEPTION , or PyTrace_C_RETURN , and arg depends on the value of what:

 Value of what Meaning of arg 
 PyTrace_CALL Always NULL. 
 PyTrace_EXCEPTION Exception information as returned by sys.exc_info() . 
 PyTrace_LINE Always NULL. 
 PyTrace_RETURN Value being returned to the caller, or NULL if caused by an exception.
 PyTrace_C_CALL Function object being called. 
 PyTrace_C_EXCEPTION Function object being called. 
 PyTrace_C_RETURN Function object being called. 
 
 int PyTrace_CALL¶

 The value of the what parameter to a Py_tracefunc function when a new call to a function or method is being reported, or a new entry into a generator. Note that the creation of the iterator for a generator function is not reported as there is no control transfer to the Python bytecode in the corresponding frame.

 int PyTrace_EXCEPTION¶

 The value of the what parameter to a Py_tracefunc function when an exception has been raised. The callback function is called with this value for what when after any bytecode is processed after which the exception becomes set within the frame being executed. The effect of this is that as exception propagation causes the Python stack to unwind, the callback is called upon return to each frame as the exception propagates. Only trace functions receives these events; they are not needed by the profiler.

 int PyTrace_LINE¶

 The value passed as the what parameter to a trace function (but not a profiling function) when a line-number event is being reported.

 int PyTrace_RETURN¶

 The value for the what parameter to Py_tracefunc functions when a call is returning without propagating an exception.

 int PyTrace_C_CALL¶

 The value for the what parameter to Py_tracefunc functions when a C function is about to be called.

 int PyTrace_C_EXCEPTION¶

 The value for the what parameter to Py_tracefunc functions when a C function has raised an exception.

 int PyTrace_C_RETURN¶

 The value for the what parameter to Py_tracefunc functions when a C function has returned.

 void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)¶

 Set the profiler function to func. The obj parameter is passed to the function as its first parameter, and may be any Python object, or NULL. If the profile function needs to maintain state, using a different value for obj for each thread provides a convenient and thread-safe place to store it. The profile function is called for all monitored events except the line-number events.

 void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)¶

 Set the tracing function to func. This is similar to PyEval_SetProfile() , except the tracing function does receive line-number events.

 PyObject* PyEval_GetCallStats(PyObject *self)¶

 Return a tuple of function call counts. There are constants defined for the positions within the tuple:

 Name Value
 PCALL_ALL 0 
 PCALL_FUNCTION 1 
 PCALL_FAST_FUNCTION 2 
 PCALL_FASTER_FUNCTION 3 
 PCALL_METHOD 4 
 PCALL_BOUND_METHOD 5 
 PCALL_CFUNCTION 6 
 PCALL_TYPE 7 
 PCALL_GENERATOR 8 
 PCALL_OTHER 9 
 PCALL_POP 10 
 

 PCALL_FAST_FUNCTION means no argument tuple needs to be created. PCALL_FASTER_FUNCTION means that the fast-path frame setup code is used.

 If there is a method call where the call can be optimized by changing the argument tuple and calling the function directly, it gets recorded twice.

 This function is only present if Python is compiled with CALL_PROFILE defined.

 Advanced Debugger Support¶

 These functions are only intended to be used by advanced debugging tools.

 PyInterpreterState* PyInterpreterState_Head()¶

 Return the interpreter state object at the head of the list of all such objects.

 PyInterpreterState* PyInterpreterState_Next(PyInterpreterState *interp)¶

 Return the next interpreter state object after interp from the list of all such objects.

 PyThreadState * PyInterpreterState_ThreadHead(PyInterpreterState *interp)¶

 Return the a pointer to the first PyThreadState object in the list of threads associated with the interpreter interp.

 PyThreadState* PyThreadState_Next(PyThreadState *tstate)¶

 Return the next thread state object after tstate from the list of all such objects belonging to the same PyInterpreterState object.

 Table Of Contents

 * Initialization, Finalization, and Threads
 + Initializing and finalizing the interpreter
 + Process-wide parameters
 + Thread State and the Global Interpreter Lock
 o Releasing the GIL from extension code
 o Non-Python created threads
 o High-level API
 o Low-level API
 + Sub-interpreter support
 o Bugs and caveats
 + Asynchronous Notifications
 + Profiling and Tracing
 + Advanced Debugger Support

 Previous topic

 Code Objects

 Next topic

 Memory Management

 This Page

 * Report a Bug
 * Show Source

 Navigation

 * index
 * modules |
 * next |
 * previous |
 * 
 * Python »
 * 3.3.7 Documentation »
 * Python/C API Reference Manual »
 © Copyright 1990-2017, Python Software Foundation.
 The Python Software Foundation is a non-profit corporation. Please donate.
 Last updated on Sep 19, 2017. Found a bug?
 Created using Sphinx 1.2.
Initializing and finalizing the interpreter¶ 
void ¶ 
 Initialize the Python interpreter. In an application embedding Python, this
should be called before using any other Python/C API functions; with the
exception of  ,   and  . This initializes
the table of loaded modules (), and creates the fundamental
modules  ,   and  . It also initializes
the module search path (). It does not set ; use
  for that. This is a no-op when called for a second time
(without calling   first). There is no return value; it is a
fatal error if the initialization fails.
 
void int initsigs ¶ 
 This function works like   if initsigs is 1. If
initsigs is 0, it skips initialization registration of signal handlers, which
might be useful when Python is embedded.
 
int ¶ 
 Return true (nonzero) when the Python interpreter has been initialized, false
(zero) if not. After   is called, this returns false until
  is called again.
 
void ¶ 
 Undo all initializations made by   and subsequent use of
Python/C API functions, and destroy all sub-interpreters (see
  below) that were created and not yet destroyed since
the last call to  . Ideally, this frees all memory
allocated by the Python interpreter. This is a no-op when called for a second
time (without calling   again first). There is no return
value; errors during finalization are ignored.
This function is provided for a number of reasons. An embedding application
might want to restart Python without having to restart the application itself.
An application that has loaded the Python interpreter from a dynamically
loadable library (or DLL) might want to free all memory allocated by Python
before unloading the DLL. During a hunt for memory leaks in an application a
developer might want to free all memory allocated by Python before exiting from
the application.
 Bugs and caveats: The destruction of modules and objects in modules is done
in random order; this may cause destructors (  methods) to fail
when they depend on other objects (even functions) or modules. Dynamically
loaded extension modules loaded by Python are not unloaded. Small amounts of
memory allocated by the Python interpreter may not be freed (if you find a leak,
please report it). Memory tied up in circular references between objects is not
freed. Some memory allocated by extension modules may not be freed. Some
extensions may not work properly if their initialization routine is called more
than once; this can happen if an application calls   and
  more than once.
 
Process-wide parameters¶ 
void wchar_t *name ¶ 
 This function should be called before   is called for
the first time, if it is called at all. It tells the interpreter the value
of the argument to the function of the program
(converted to wide characters).
This is used by   and some other functions below to find
the Python run-time libraries relative to the interpreter executable. The
default value is . The argument should point to a
zero-terminated wide character string in static storage whose contents will not
change for the duration of the program’s execution. No code in the Python
interpreter will change the contents of this storage.
 
wchar* ¶ 
 Return the program name set with  , or the default.
The returned string points into static storage; the caller should not modify its
value.
 
wchar_t* ¶ 
 Return the prefix for installed platform-independent files. This is derived
through a number of complicated rules from the program name set with
  and some environment variables; for example, if the
program name is , the prefix is . The
returned string points into static storage; the caller should not modify its
value. This corresponds to the prefix variable in the top-level
 and the argument to the configure
script at build time. The value is available to Python code as .
It is only useful on Unix. See also the next function.
 
wchar_t* ¶ 
 Return the exec-prefix for installed platform-dependent files. This is
derived through a number of complicated rules from the program name set with
  and some environment variables; for example, if the
program name is , the exec-prefix is
. The returned string points into static storage; the caller
should not modify its value. This corresponds to the exec_prefix
variable in the top-level and the 
argument to the configure script at build time. The value is
available to Python code as . It is only useful on Unix.
Background: The exec-prefix differs from the prefix when platform dependent
files (such as executables and shared libraries) are installed in a different
directory tree. In a typical installation, platform dependent files may be
installed in the subtree while platform independent may
be installed in .
Generally speaking, a platform is a combination of hardware and software
families, e.g. Sparc machines running the Solaris 2.x operating system are
considered the same platform, but Intel machines running Solaris 2.x are another
platform, and Intel machines running Linux are yet another platform. Different
major revisions of the same operating system generally also form different
platforms. Non-Unix operating systems are a different story; the installation
strategies on those systems are so different that the prefix and exec-prefix are
meaningless, and set to the empty string. Note that compiled Python bytecode
files are platform independent (but not independent from the Python version by
which they were compiled!).
System administrators will know how to configure the mount or
automount programs to share between platforms
while having be a different filesystem for each
platform.
 
wchar_t* ¶ 
 Return the full program name of the Python executable; this is computed as a
side-effect of deriving the default module search path from the program name
(set by   above). The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as .
 
wchar_t* ¶ 
 Return the default module search path; this is computed from the program name
(set by   above) and some environment variables.
The returned string consists of a series of directory names separated by a
platform dependent delimiter character. The delimiter character is 
on Unix and Mac OS X, on Windows. The returned string points into
static storage; the caller should not modify its value. The list
  is initialized with this value on interpreter startup; it
can be (and usually is) modified later to change the search path for loading
modules.
 
void const wchar_t * ¶ 
 Set the default module search path. If this function is called before
 , then   won’t attempt to compute a
default search path but uses the one provided instead. This is useful if
Python is embedded by an application that has full knowledge of the location
of all modules. The path components should be separated by semicolons.
This also causes   to be set only to the raw program
name (see  ) and for   and
  to be empty. It is up to the caller to modify these
if required after calling  .
 
const char* ¶ 
 Return the version of this Python interpreter. This is a string that looks
something like
 
 
The first word (up to the first space character) is the current Python version;
the first three characters are the major and minor version separated by a
period. The returned string points into static storage; the caller should not
modify its value. The value is available to Python code as  .
 
const char* ¶ 
 Return the platform identifier for the current platform. On Unix, this is
formed from the “official” name of the operating system, converted to lower
case, followed by the major revision number; e.g., for Solaris 2.x, which is
also known as SunOS 5.x, the value is . On Mac OS X, it is
. On Windows, it is . The returned string points into
static storage; the caller should not modify its value. The value is available
to Python code as .
 
const char* ¶ 
 Return the official copyright string for the current Python version, for example
 
The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as .
 
const char* ¶ 
 Return an indication of the compiler used to build the current Python version,
in square brackets, for example:
The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as part of the variable
.
 
const char* ¶ 
 Return information about the sequence number and build date and time of the
current Python interpreter instance, for example
 
 
The returned string points into static storage; the caller should not modify its
value. The value is available to Python code as part of the variable
.
 
void int argc, wchar_t **argv, int updatepath ¶ 
 Set   based on argc and argv. These parameters are
similar to those passed to the program’s function with the
difference that the first entry should refer to the script file to be
executed rather than the executable hosting the Python interpreter. If there
isn’t a script that will be run, the first entry in argv can be an empty
string. If this function fails to initialize  , a fatal
condition is signalled using  .
If updatepath is zero, this is all the function does. If updatepath
is non-zero, the function also modifies   according to the
following algorithm:
If the name of an existing script is passed in , the absolute
path of the directory where the script is located is prepended to
 .
Otherwise (that is, if argc is 0 or doesn’t point
to an existing file name), an empty string is prepended to
 , which is the same as prepending the current working
directory ().
Note
It is recommended that applications embedding the Python interpreter
for purposes other than executing a single script pass 0 as updatepath,
and update   themselves if desired.
See CVE-2008-5983.
On versions before 3.1.3, you can achieve the same effect by manually
popping the first   element after having called
 , for example using:
 
 
 
 
void int argc, wchar_t **argv ¶ 
 This function works like   with updatepath set to 1.
 
void wchar_t *home ¶ 
 Set the default “home” directory, that is, the location of the standard
Python libraries. See   for the meaning of the
argument string.
The argument should point to a zero-terminated character string in static
storage whose contents will not change for the duration of the program’s
execution. No code in the Python interpreter will change the contents of
this storage.
 
w_char* ¶ 
 Return the default “home”, that is, the value set by a previous call to
 , or the value of the  
environment variable if it is set.
 
Thread State and the Global Interpreter Lock¶ 
The Python interpreter is not fully thread-safe. In order to support
multi-threaded Python programs, there’s a global lock, called the  global
interpreter lock  or  GIL , that must be held by the current thread before
it can safely access Python objects. Without the lock, even the simplest
operations could cause problems in a multi-threaded program: for example, when
two threads simultaneously increment the reference count of the same object, the
reference count could end up being incremented only once instead of twice.
Therefore, the rule exists that only the thread that has acquired the
 GIL  may operate on Python objects or call Python/C API functions.
In order to emulate concurrency of execution, the interpreter regularly
tries to switch threads (see  ). The lock is also
released around potentially blocking I/O operations like reading or writing
a file, so that other Python threads can run in the meantime.
The Python interpreter keeps some thread-specific bookkeeping information
inside a data structure called  . There’s also one
global variable pointing to the current  : it can
be retrieved using  .
Releasing the GIL from extension code¶ 
Most extension code manipulating the  GIL  has the following simple
structure:
  
 
 
 
 
 
This is so common that a pair of macros exists to simplify it:
 
 
 
The   macro opens a new block and declares a
hidden local variable; the   macro closes the
block. These two macros are still available when Python is compiled without
thread support (they simply have an empty expansion).
When thread support is enabled, the block above expands to the following code:
  
 
 
 
Here is how these functions work: the global interpreter lock is used to protect the pointer to the
current thread state. When releasing the lock and saving the thread state,
the current thread state pointer must be retrieved before the lock is released
(since another thread could immediately acquire the lock and store its own thread
state in the global variable). Conversely, when acquiring the lock and restoring
the thread state, the lock must be acquired before storing the thread state
pointer.
Note
Calling system I/O functions is the most common use case for releasing
the GIL, but it can also be useful before calling long-running computations
which don’t need access to Python objects, such as compression or
cryptographic functions operating over memory buffers. For example, the
standard   and   modules release the GIL when
compressing or hashing data.
Non-Python created threads¶ 
When threads are created using the dedicated Python APIs (such as the
  module), a thread state is automatically associated to them
and the code showed above is therefore correct. However, when threads are
created from C (for example by a third-party library with its own thread
management), they don’t hold the GIL, nor is there a thread state structure
for them.
If you need to call Python code from these threads (often this will be part
of a callback API provided by the aforementioned third-party library),
you must first register these threads with the interpreter by
creating a thread state data structure, then acquiring the GIL, and finally
storing their thread state pointer, before you can start using the Python/C
API. When you are done, you should reset the thread state pointer, release
the GIL, and finally free the thread state data structure.
The   and   functions do
all of the above automatically. The typical idiom for calling into Python
from a C thread is:
  
 
 
 
Note that the functions assume there is only one global
interpreter (created automatically by  ). Python
supports the creation of additional interpreters (using
 ), but mixing multiple interpreters and the
 API is unsupported.
Another important thing to note about threads is their behaviour in the face
of the C call. On most systems with , after a
process forks only the thread that issued the fork will exist. That also
means any locks held by other threads will never be released. Python solves
this for   by acquiring the locks it uses internally before
the fork, and releasing them afterwards. In addition, it resets any
 Lock Objects  in the child. When extending or embedding Python, there
is no way to inform Python of additional (non-Python) locks that need to be
acquired before or reset after a fork. OS facilities such as
 would need to be used to accomplish the same thing.
Additionally, when extending or embedding Python, calling 
directly rather than through   (and returning to or calling
into Python) may result in a deadlock by one of Python’s internal locks
being held by a thread that is defunct after the fork.
  tries to reset the necessary locks, but is not
always able to.
High-level API¶ 
These are the most commonly used types and functions when writing C extension
code, or when embedding the Python interpreter:
¶ 
 This data structure represents the state shared by a number of cooperating
threads. Threads belonging to the same interpreter share their module
administration and a few other internal items. There are no public members in
this structure.
Threads belonging to different interpreters initially share nothing, except
process state like available memory, open file descriptors and such. The global
interpreter lock is also shared by all threads, regardless of to which
interpreter they belong.
 
¶ 
 This data structure represents the state of a single thread. The only public
data member is  , which points to
this thread’s interpreter state.
 
void ¶ 
 Initialize and acquire the global interpreter lock. It should be called in the
main thread before creating a second thread or engaging in any other thread
operations such as . It is not needed before
calling   or  .
This is a no-op when called for a second time.
This function cannot be called before   anymore.
Note
When only the main thread exists, no GIL operations are needed. This is a
common situation (most Python programs do not use threads), and the lock
operations slow the interpreter down a bit. Therefore, the lock is not
created initially. This situation is equivalent to having acquired the lock:
when there is only a single thread, all object accesses are safe. Therefore,
when this function initializes the global interpreter lock, it also acquires
it. Before the Python   module creates a new thread, knowing
that either it has the lock or the lock hasn’t been created yet, it calls
 . When this call returns, it is guaranteed that
the lock has been created and that the calling thread has acquired it.
It is not safe to call this function when it is unknown which thread (if
any) currently has the global interpreter lock.
This function is not available when thread support is disabled at compile time.
 
int ¶ 
 Returns a non-zero value if   has been called. This
function can be called without holding the GIL, and therefore can be used to
avoid calls to the locking API when running single-threaded. This function is
not available when thread support is disabled at compile time.
 
PyThreadState* ¶ 
 Release the global interpreter lock (if it has been created and thread
support is enabled) and reset the thread state to NULL, returning the
previous thread state (which is not NULL). If the lock has been created,
the current thread must have acquired it. (This function is available even
when thread support is disabled at compile time.)
 
void PyThreadState  *tstate ¶ 
 Acquire the global interpreter lock (if it has been created and thread
support is enabled) and set the thread state to tstate, which must not be
NULL. If the lock has been created, the current thread must not have
acquired it, otherwise deadlock ensues. (This function is available even
when thread support is disabled at compile time.)
 
PyThreadState* ¶ 
 Return the current thread state. The global interpreter lock must be held.
When the current thread state is NULL, this issues a fatal error (so that
the caller needn’t check for NULL).
 
PyThreadState* PyThreadState  *tstate ¶ 
 Swap the current thread state with the thread state given by the argument
tstate, which may be NULL. The global interpreter lock must be held
and is not released.
 
void ¶ 
 This function is called from   to ensure that newly
created child processes don’t hold locks referring to threads which
are not running in the child process.
 
The following functions use thread-local storage, and are not compatible
with sub-interpreters:
PyGILState_STATE ¶ 
 Ensure that the current thread is ready to call the Python C API regardless
of the current state of Python, or of the global interpreter lock. This may
be called as many times as desired by a thread as long as each call is
matched with a call to  . In general, other
thread-related APIs may be used between   and
  calls as long as the thread state is restored to
its previous state before the Release(). For example, normal usage of the
  and   macros is
acceptable.
The return value is an opaque “handle” to the thread state when
  was called, and must be passed to
  to ensure Python is left in the same state. Even
though recursive calls are allowed, these handles cannot be shared - each
unique call to   must save the handle for its call
to  .
When the function returns, the current thread will hold the GIL and be able
to call arbitrary Python code. Failure is a fatal error.
 
void PyGILState_STATE¶ 
 Release any resources previously acquired. After this call, Python’s state will
be the same as it was prior to the corresponding   call
(but generally this state will be unknown to the caller, hence the use of the
GILState API).
Every call to   must be matched by a call to
  on the same thread.
 
PyThreadState* ¶ 
 Get the current thread state for this thread. May return if no
GILState API has been used on the current thread. Note that the main thread
always has such a thread-state, even if no auto-thread-state call has been
made on the main thread. This is mainly a helper/diagnostic function.
 
The following macros are normally used without a trailing semicolon; look for
example usage in the Python source distribution.
¶ 
 This macro expands to .
Note that it contains an opening brace; it must be matched with a following
  macro. See above for further discussion of this
macro. It is a no-op when thread support is disabled at compile time.
 
¶ 
 This macro expands to . Note that it contains
a closing brace; it must be matched with an earlier
  macro. See above for further discussion of
this macro. It is a no-op when thread support is disabled at compile time.
 
¶ 
 This macro expands to : it is equivalent to
  without the closing brace. It is a no-op when
thread support is disabled at compile time.
 
¶ 
 This macro expands to : it is equivalent to
  without the opening brace and variable
declaration. It is a no-op when thread support is disabled at compile time.
 
Low-level API¶ 
All of the following functions are only available when thread support is enabled
at compile time, and must be called only when the global interpreter lock has
been created.
PyInterpreterState* ¶ 
 Create a new interpreter state object. The global interpreter lock need not
be held, but may be held if it is necessary to serialize calls to this
function.
 
void PyInterpreterState  *interp ¶ 
 Reset all information in an interpreter state object. The global interpreter
lock must be held.
 
void PyInterpreterState  *interp ¶ 
 Destroy an interpreter state object. The global interpreter lock need not be
held. The interpreter state must have been reset with a previous call to
 .
 
PyThreadState* PyInterpreterState  *interp ¶ 
 Create a new thread state object belonging to the given interpreter object.
The global interpreter lock need not be held, but may be held if it is
necessary to serialize calls to this function.
 
void PyThreadState  *tstate ¶ 
 Reset all information in a thread state object. The global interpreter lock
must be held.
 
void PyThreadState  *tstate ¶ 
 Destroy a thread state object. The global interpreter lock need not be held.
The thread state must have been reset with a previous call to
 .
 
PyObject* ¶ 
 Return value: Borrowed reference. Return a dictionary in which extensions can store thread-specific state
information. Each extension should use a unique key to use to store state in
the dictionary. It is okay to call this function when no current thread state
is available. If this function returns NULL, no exception has been raised and
the caller should assume no current thread state is available.
 
int long id, PyObject  *exc ¶ 
 Asynchronously raise an exception in a thread. The id argument is the thread
id of the target thread; exc is the exception object to be raised. This
function does not steal any references to exc. To prevent naive misuse, you
must write your own C extension to call this. Must be called with the GIL held.
Returns the number of thread states modified; this is normally one, but will be
zero if the thread id isn’t found. If exc is , the pending
exception (if any) for the thread is cleared. This raises no exceptions.
 
void PyThreadState  *tstate ¶ 
 Acquire the global interpreter lock and set the current thread state to
tstate, which should not be NULL. The lock must have been created earlier.
If this thread already has the lock, deadlock ensues.
   is a higher-level function which is always
available (even when thread support isn’t enabled or when threads have
not been initialized).
 
void PyThreadState  *tstate ¶ 
 Reset the current thread state to NULL and release the global interpreter
lock. The lock must have been created earlier and must be held by the current
thread. The tstate argument, which must not be NULL, is only used to check
that it represents the current thread state — if it isn’t, a fatal error is
reported.
   is a higher-level function which is always
available (even when thread support isn’t enabled or when threads have
not been initialized).
 
void ¶ 
 Acquire the global interpreter lock. The lock must have been created earlier.
If this thread already has the lock, a deadlock ensues.
This function does not update the current thread state. Please use
  or  
instead.
 
void ¶ 
 Release the global interpreter lock. The lock must have been created earlier.
This function does not update the current thread state. Please use
  or  
instead.
 
Sub-interpreter support¶ 
While in most uses, you will only embed a single Python interpreter, there
are cases where you need to create several independent interpreters in the
same process and perhaps even in the same thread. Sub-interpreters allow
you to do that. You can switch between sub-interpreters using the
  function. You can create and destroy them
using the following functions:
PyThreadState* ¶ 
 Create a new sub-interpreter. This is an (almost) totally separate environment
for the execution of Python code. In particular, the new interpreter has
separate, independent versions of all imported modules, including the
fundamental modules  ,   and  . The
table of loaded modules () and the module search path
() are also separate. The new environment has no 
variable. It has new standard I/O stream file objects ,
 and (however these refer to the same underlying
file descriptors).
The return value points to the first thread state created in the new
sub-interpreter. This thread state is made in the current thread state.
Note that no actual thread is created; see the discussion of thread states
below. If creation of the new interpreter is unsuccessful, NULL is
returned; no exception is set since the exception state is stored in the
current thread state and there may not be a current thread state. (Like all
other Python/C API functions, the global interpreter lock must be held before
calling this function and is still held when it returns; however, unlike most
other Python/C API functions, there needn’t be a current thread state on
entry.)
Extension modules are shared between (sub-)interpreters as follows: the first
time a particular extension is imported, it is initialized normally, and a
(shallow) copy of its module’s dictionary is squirreled away. When the same
extension is imported by another (sub-)interpreter, a new module is initialized
and filled with the contents of this copy; the extension’s function is
not called. Note that this is different from what happens when an extension is
imported after the interpreter has been completely re-initialized by calling
  and  ; in that case, the extension’s
 function is called again.
 
void PyThreadState  *tstate ¶ 
 Destroy the (sub-)interpreter represented by the given thread state. The given
thread state must be the current thread state. See the discussion of thread
states below. When the call returns, the current thread state is NULL. All
thread states associated with this interpreter are destroyed. (The global
interpreter lock must be held before calling this function and is still held
when it returns.)   will destroy all sub-interpreters that
haven’t been explicitly destroyed at that point.
 
Bugs and caveats¶ 
Because sub-interpreters (and the main interpreter) are part of the same
process, the insulation between them isn’t perfect — for example, using
low-level file operations like   they can
(accidentally or maliciously) affect each other’s open files. Because of the
way extensions are shared between (sub-)interpreters, some extensions may not
work properly; this is especially likely when the extension makes use of
(static) global variables, or when the extension manipulates its module’s
dictionary after its initialization. It is possible to insert objects created
in one sub-interpreter into a namespace of another sub-interpreter; this should
be done with great care to avoid sharing user-defined functions, methods,
instances or classes between sub-interpreters, since import operations executed
by such objects may affect the wrong (sub-)interpreter’s dictionary of loaded
modules.
Also note that combining this functionality with APIs
is delicate, because these APIs assume a bijection between Python thread states
and OS-level threads, an assumption broken by the presence of sub-interpreters.
It is highly recommended that you don’t switch sub-interpreters between a pair
of matching   and   calls.
Furthermore, extensions (such as  ) using these APIs to allow calling
of Python code from non-Python created threads will probably be broken when using
sub-interpreters.
Asynchronous Notifications¶ 
A mechanism is provided to make asynchronous notifications to the main
interpreter thread. These notifications take the form of a function
pointer and a void pointer argument.
int int (*func)(void *), void *arg ¶ 
 Schedule a function to be called from the main interpreter thread. On
success, 0 is returned and func is queued for being called in the
main thread. On failure, -1 is returned without setting any exception.
When successfully queued, func will be eventually called from the
main interpreter thread with the argument arg. It will be called
asynchronously with respect to normally running Python code, but with
both these conditions met:
on a  bytecode  boundary;
with the main thread holding the  global interpreter lock 
(func can therefore use the full C API).
 func must return 0 on success, or -1 on failure with an exception
set. func won’t be interrupted to perform another asynchronous
notification recursively, but it can still be interrupted to switch
threads if the global interpreter lock is released.
This function doesn’t need a current thread state to run, and it doesn’t
need the global interpreter lock.
Warning
This is a low-level function, only useful for very special cases.
There is no guarantee that func will be called as quick as
possible. If the main thread is busy executing a system call,
func won’t be called before the system call returns. This
function is generally not suitable for calling Python code from
arbitrary C threads. Instead, use the  PyGILState API .
 
 
Profiling and Tracing¶ 
The Python interpreter provides some low-level support for attaching profiling
and execution tracing facilities. These are used for profiling, debugging, and
coverage analysis tools.
This C interface allows the profiling or tracing code to avoid the overhead of
calling through Python-level callable objects, making a direct C function call
instead. The essential attributes of the facility have not changed; the
interface allows trace functions to be installed per-thread, and the basic
events reported to the trace function are the same as had been reported to the
Python-level trace functions in previous versions.
int PyObject  *obj, PyFrameObject *frame, int what, PyObject  *arg ¶ 
 The type of the trace function registered using   and
 . The first parameter is the object passed to the
registration function as obj, frame is the frame object to which the event
pertains, what is one of the constants ,
, , ,
, , or
, and arg depends on the value of what:
 Value of what 
Meaning of arg 
  
Always NULL.
  
Exception information as returned by
 .
  
Always NULL.
  
Value being returned to the caller,
or NULL if caused by an exception.
  
Function object being called.
  
Function object being called.
  
Function object being called.
 
int ¶ 
 The value of the what parameter to a   function when a new
call to a function or method is being reported, or a new entry into a generator.
Note that the creation of the iterator for a generator function is not reported
as there is no control transfer to the Python bytecode in the corresponding
frame.
 
int ¶ 
 The value of the what parameter to a   function when an
exception has been raised. The callback function is called with this value for
what when after any bytecode is processed after which the exception becomes
set within the frame being executed. The effect of this is that as exception
propagation causes the Python stack to unwind, the callback is called upon
return to each frame as the exception propagates. Only trace functions receives
these events; they are not needed by the profiler.
 
int ¶ 
 The value passed as the what parameter to a trace function (but not a
profiling function) when a line-number event is being reported.
 
int ¶ 
 The value for the what parameter to   functions when a
call is returning without propagating an exception.
 
int ¶ 
 The value for the what parameter to   functions when a C
function is about to be called.
 
int ¶ 
 The value for the what parameter to   functions when a C
function has raised an exception.
 
int ¶ 
 The value for the what parameter to   functions when a C
function has returned.
 
void Py_tracefunc  func, PyObject  *obj ¶ 
 Set the profiler function to func. The obj parameter is passed to the
function as its first parameter, and may be any Python object, or NULL. If
the profile function needs to maintain state, using a different value for obj
for each thread provides a convenient and thread-safe place to store it. The
profile function is called for all monitored events except the line-number
events.
 
void Py_tracefunc  func, PyObject  *obj ¶ 
 Set the tracing function to func. This is similar to
 , except the tracing function does receive line-number
events.
 
PyObject* PyObject  *self ¶ 
 Return a tuple of function call counts. There are constants defined for the
positions within the tuple:
 Name
Value
  
0
  
1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
 means no argument tuple needs to be created.
 means that the fast-path frame setup code is used.
If there is a method call where the call can be optimized by changing
the argument tuple and calling the function directly, it gets recorded
twice.
This function is only present if Python is compiled with 
defined.
 
Advanced Debugger Support¶ 
These functions are only intended to be used by advanced debugging tools.
PyInterpreterState* ¶ 
 Return the interpreter state object at the head of the list of all such objects.
 
PyInterpreterState* PyInterpreterState  *interp ¶ 
 Return the next interpreter state object after interp from the list of all
such objects.
 
PyThreadState * PyInterpreterState  *interp ¶ 
 Return the a pointer to the first   object in the list of
threads associated with the interpreter interp.
 
PyThreadState* PyThreadState  *tstate ¶ 
 Return the next thread state object after tstate from the list of all such
objects belonging to the same   object.
Initialization, Finalization, and Threads — Python 3.3.7 documentation
https://docs.python.org/3.3/c-api/init.html?highlight=gil