{"id":329502,"date":"2023-09-13T14:00:00","date_gmt":"2023-09-13T14:00:00","guid":{"rendered":"https:\/\/realpython.com\/python-parallel-processing\/"},"modified":"2023-09-13T14:00:00","modified_gmt":"2023-09-13T14:00:00","slug":"bypassing-the-gil-for-parallel-processing-in-python","status":"publish","type":"post","link":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/2023\/09\/13\/bypassing-the-gil-for-parallel-processing-in-python\/","title":{"rendered":"Bypassing the GIL for Parallel Processing in Python"},"content":{"rendered":"<p class=\"syndicated-attribution\"><meta name= \\\"keywords \\\" content= \\\"\u96fb\u5b50\u8a08\u7b97\u6a5f, \u6559\u80b2, IT \u96fb\u8166\u73ed,\u96fb\u8166\u88dc\u7fd2\uff0c \u96fb\u8166\u73ed\uff0c \u5bb6\u6559\uff0c \u79c1\u4eba\u8001\u5e2b\uff0c \u8cc7\u8a0a\u6280\u8853\uff0c \u7a0b\u5e8f\u8a2d\u8a08\uff0c \u96fb\u5b50\u8a08\u7b97\u6a5f\uff0c \u904a\u6232\uff0c \u860b\u679c\uff0c \u96fb\u5f71\uff0c \u8a08\u7b97\u6a5f\uff0c\u7de8\u78bc\uff0c Java\uff0c C\/C++\uff0c JavaScript\uff0c PHP\uff0c HTML\uff0c CSS\uff0c MySQL\uff0c mobile\uff0c Android\uff0c \u52d5\u6f2b\uff0c Python\uff0c teacher\uff0c \u88dc\u7fd2\uff0c \u96fb\u8166\u88dc\u7fd2 \u8cc7\u8a0a, \u7535\u5b50\u8ba1\u7b97\u673a, IT ,Game, apple, movie, Computer,student,Java,\u6559\u80b2, ,\u5b66\u751f, \u5b66\u4e60, learn, \u6559\u5b66,  Android, apple,anime, animation, \u4fe1\u606f\u6280\u672f, \u7a0b\u5e8f\u8bbe\u8ba1, \u79fb\u52a8\u7535\u8bdd, \u8cc7\u8a0a\u79d1\u6280,Game, Jeu, Juego,Call Of Duty ,\u4f7f\u547d\u53ec\u559a , \u6e38\u620f, \u7535\u5b50\u6e38\u620f,, \u591a\u4eba\u7535\u5b50\u6e38\u620f, \u7f51\u7edc\u6e38\u620f\uff0conline\uff0conline game, \u624b\u673a\u6e38\u620f, mobile \\\"><\/p>\n<div>\n<p>Unlocking Python\u2019s true potential in terms of speed through <a href=\"https:\/\/en.wikipedia.org\/wiki\/Parallel_programming_model#Shared_memory\">shared-memory parallelism<\/a> has traditionally been limited and challenging to achieve. That\u2019s because the <a href=\"https:\/\/realpython.com\/python-gil\/\">global interpreter lock (GIL)<\/a> doesn\u2019t allow for thread-based parallel processing in Python. Fortunately, there are several work-arounds for this notorious limitation, which you\u2019re about to explore now!<\/p>\n<p><strong>In this tutorial, you\u2019ll learn how to:<\/strong><\/p>\n<ul>\n<li>Run <strong>Python threads<\/strong> in parallel on multiple CPU cores<\/li>\n<li>Avoid the <strong>data serialization<\/strong> overhead of multiprocessing<\/li>\n<li><strong>Share memory<\/strong> between Python and C runtime environments<\/li>\n<li>Use different strategies to <strong>bypass the GIL<\/strong> in Python<\/li>\n<li><strong>Parallelize<\/strong> your Python programs to improve their performance<\/li>\n<li>Build a sample desktop application for <strong>parallel image processing<\/strong><\/li>\n<\/ul>\n<p>To get the most out of this advanced tutorial, you should understand the difference between <a href=\"https:\/\/realpython.com\/python-concurrency\/#what-is-concurrency\">concurrency<\/a> and <a href=\"https:\/\/realpython.com\/python-concurrency\/#what-is-parallelism\">parallelism<\/a>. You\u2019ll benefit from having previous experience with <a href=\"https:\/\/realpython.com\/intro-to-python-threading\/\">multithreading<\/a> in programming languages other than Python. Finally, it\u2019s best if you\u2019re eager to explore uncharted territory, such as calling <a href=\"https:\/\/realpython.com\/python-bindings-overview\/\">foreign Python bindings<\/a> or writing bits of <a href=\"https:\/\/realpython.com\/c-for-python-programmers\/\">C code<\/a>.<\/p>\n<p>Don\u2019t worry if your knowledge of parallel processing is a bit rusty, as you\u2019ll have a chance to quickly refresh your memory in the upcoming sections. Also, note that you\u2019ll find all the code samples, image files, and the demo project from this tutorial in the supporting materials, which you can download below:<\/p>\n<div class=\"alert alert-warning\" role=\"alert\">\n<p><strong markdown=\"1\">Get Your Code:<\/strong> <a href=\"https:\/\/realpython.com\/bonus\/python-parallel-processing-code\/\" class=\"alert-link\" data-toggle=\"modal\" data- data-focus=\"false\" markdown=\"1\">Click here to download the free sample code<\/a> that shows you how to bypass the GIL and achieve parallel processing in Python.<\/p>\n<\/div>\n<h2 id=\"recall-the-fundamentals-of-parallel-processing\">Recall the Fundamentals of Parallel Processing<a class=\"headerlink\" href=\"https:\/\/realpython.com\/python-parallel-processing\/#recall-the-fundamentals-of-parallel-processing\" title=\"Permanent link\"><\/a><\/h2>\n<p>Before dipping your toes into specific ways of bypassing the GIL in Python, you might want to revisit some related topics. Over the following few sections, you\u2019ll familiarize yourself with different computer processing models, task types, abstractions over modern CPUs, and some history. If you already know this information, then feel free to jump ahead to the <a href=\"https:\/\/realpython.com\/python-parallel-processing\/#use-process-based-parallelism-instead-of-multithreading\">classic mechanism<\/a> for parallelization in Python.<\/p>\n<h3 id=\"whats-parallel-processing\">What\u2019s Parallel Processing?<a class=\"headerlink\" href=\"https:\/\/realpython.com\/python-parallel-processing\/#whats-parallel-processing\" title=\"Permanent link\"><\/a><\/h3>\n<p>Under <a href=\"https:\/\/en.wikipedia.org\/wiki\/Flynn%27s_taxonomy\">Flynn\u2019s taxonomy<\/a>, the most common types of <strong>parallel processing<\/strong> allow you to run the same (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Single_instruction,_multiple_data\">SIMD<\/a>) or different code fragments (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Multiple_instruction,_multiple_data\">MIMD<\/a>) in separate execution streams at the same time:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png\" ><img decoding=\"async\" loading=\"lazy\" class=\"img-fluid mx-auto d-block border \" src=\"https:\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png\" width=\"960\" height=\"340\" srcset=\"https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png&amp;w=240&amp;sig=ffd8f8d2a20cc7a9acd5778a2deac46826152ca3 240w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png&amp;w=320&amp;sig=a1905552ac1dc3ba0e6060dc7265b3310c38df4e 320w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png&amp;w=480&amp;sig=099394376d17bdd39e848381b3217fd006a4d639 480w, https:\/\/files.realpython.com\/media\/parallel.bcf05cc11397.png 960w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"Parallel Execution of Tasks\" data-asset=\"5310\"><\/a><figcaption class=\"figure-caption text-center\">Parallel Execution of Tasks<\/figcaption><\/figure>\n<p>Here, two independent tasks or <a href=\"https:\/\/en.wikipedia.org\/wiki\/Job_(computing)\">jobs<\/a> execute alongside each other. To run more than one piece of code simultaneously like this, you need a computer equipped with a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Central_processing_unit\">central processing unit (CPU)<\/a> comprising <a href=\"https:\/\/en.wikipedia.org\/wiki\/Multi-core_processor\">multiple physical cores<\/a>, which is the norm nowadays. While you could alternatively access a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Computer_cluster\">cluster<\/a> of geographically <a href=\"https:\/\/en.wikipedia.org\/wiki\/Distributed_computing\">distributed machines<\/a>, you\u2019ll consider only the first option in this tutorial.<\/p>\n<p>Parallel processing is a particular form of <strong>concurrent processing<\/strong>, which is a broader term encompassing <a href=\"https:\/\/en.wikipedia.org\/wiki\/Context_switch\">context switching<\/a> between multiple tasks. It means that a currently running task might voluntarily suspend its execution or be forcibly suspended to give a slice of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/CPU_time\">CPU time<\/a> to another task:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/concurrent.f333207efd07.png\" ><img decoding=\"async\" loading=\"lazy\" class=\"img-fluid mx-auto d-block border \" src=\"https:\/\/files.realpython.com\/media\/concurrent.f333207efd07.png\" width=\"960\" height=\"340\" srcset=\"https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/concurrent.f333207efd07.png&amp;w=240&amp;sig=b2ade107b6cb187401366286311eed0517cfbac5 240w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/concurrent.f333207efd07.png&amp;w=320&amp;sig=e41e9e9fc09eeed965571bb4a8009a466cd6f3c5 320w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/concurrent.f333207efd07.png&amp;w=480&amp;sig=b72754c18b58ed0a3545fa2ec4c102edd46d28fe 480w, https:\/\/files.realpython.com\/media\/concurrent.f333207efd07.png 960w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"Concurrent Execution of Tasks\" data-asset=\"5311\"><\/a><figcaption class=\"figure-caption text-center\">Concurrent Execution of Tasks<\/figcaption><\/figure>\n<p>In this case, two tasks have been sliced into smaller and intertwined chunks of work that share a single core of the same processing unit. This is analogous to playing chess against <a href=\"https:\/\/en.wikipedia.org\/wiki\/Simultaneous_exhibition\">multiple opponents<\/a> at the same time, as shown in one of the scenes from the popular TV miniseries <a href=\"https:\/\/www.imdb.com\/title\/tt10048342\/\"><em>The Queen\u2019s Gambit<\/em><\/a>. After each move, the player proceeds to the next opponent in a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Round-robin_scheduling\">round-robin<\/a> fashion, trying to remember the state of the corresponding game.<\/p>\n<div class=\"alert alert-primary\" role=\"alert\">\n<p><strong>Note:<\/strong> Context switching makes <a href=\"https:\/\/en.wikipedia.org\/wiki\/Computer_multitasking\">multitasking<\/a> possible on single-core architectures. However, multi-core CPUs also benefit from this technique when the tasks outnumber the available processing power, which is often the case. Therefore, concurrent processing usually involves spreading the individual task slices over many CPUs, combining the power of context switching and parallel processing.<\/p>\n<\/div>\n<p>While it takes time for people to switch their focus, computers take turns much quicker. Rapid context switching gives the illusion of parallel execution despite using only one physical CPU. As a result, multiple tasks are making progress together.<\/p>\n<p>Because of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Time-sharing\">time-sharing<\/a>, the total time required to finish your intertwined tasks running concurrently is longer when compared to a genuinely parallel version. In fact, context switching has a noticeable overhead that makes the execution time even worse than if you run your tasks one after another using <strong>sequential processing<\/strong> on a single CPU. Here\u2019s what sequential processing looks like:<\/p>\n<figure class=\"js-lightbox\"><a href=\"https:\/\/files.realpython.com\/media\/sequential.f52f718348b0.png\" ><img decoding=\"async\" loading=\"lazy\" class=\"img-fluid mx-auto d-block border \" src=\"https:\/\/files.realpython.com\/media\/sequential.f52f718348b0.png\" width=\"960\" height=\"340\" srcset=\"https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/sequential.f52f718348b0.png&amp;w=240&amp;sig=03b32ff48639019af2d4244fdc71c09cdf382e61 240w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/sequential.f52f718348b0.png&amp;w=320&amp;sig=b5d4c4a6a64e97108e0f57eabcb4fb81dd46fb63 320w, https:\/\/robocrop.realpython.net\/?url=https%3A\/\/files.realpython.com\/media\/sequential.f52f718348b0.png&amp;w=480&amp;sig=4857ffca1bdb8d4d66eca62cccd4bf38d1d411da 480w, https:\/\/files.realpython.com\/media\/sequential.f52f718348b0.png 960w\" sizes=\"(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)\" alt=\"Sequential Execution of Tasks\" data-asset=\"5312\"><\/a><figcaption class=\"figure-caption text-center\">Sequential Execution of Tasks<\/figcaption><\/figure>\n<p>With sequential processing, you don\u2019t start another task until the previous one finishes, so you don\u2019t have the costs of switching back and forth. This situation corresponds to playing an entire chess game with one opponent before moving on to the next one. Meanwhile, the remaining players must sit tight, patiently waiting for their turn.<\/p>\n<p>On the other hand, playing multiple games concurrently can maximize your <a href=\"https:\/\/en.wikipedia.org\/wiki\/Network_throughput\">throughput<\/a>. When you prioritize games with players who make quick decisions over those who need more time to think, then you\u2019ll finish more games sooner. Therefore, intertwining can improve the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Latency_(engineering)\">latency<\/a>, or <strong>response times<\/strong>, of the individual tasks, even when you only have one stream of execution.<\/p>\n<p>As you can probably tell, choosing between <strong>parallel<\/strong>, <strong>concurrent<\/strong>, and <strong>sequential<\/strong> processing models can feel like plotting out your next three moves in chess. You have to consider several factors, so there\u2019s no one-size-fits-all solution.<\/p>\n<p>Whether context switching actually helps will depend on how you prioritize your tasks. Inefficient task scheduling can lead to <a href=\"https:\/\/en.wikipedia.org\/wiki\/Starvation_(computer_science)\">starving<\/a> shorter tasks of CPU time.<\/p>\n<p>Additionally, the types of tasks are critical. Two broad categories of concurrent tasks are <strong>CPU-bound<\/strong> and <strong>I\/O-bound<\/strong> ones. The CPU-bound tasks will only benefit from truly parallel execution to run faster, whereas I\/O-bound tasks can leverage concurrent processing to reduce latency. You\u2019ll learn more about these categories\u2019 characteristics now.<\/p>\n<h3 id=\"how-do-cpu-bound-and-io-bound-tasks-differ\">How Do CPU-Bound and I\/O-Bound Tasks Differ?<a class=\"headerlink\" href=\"https:\/\/realpython.com\/python-parallel-processing\/#how-do-cpu-bound-and-io-bound-tasks-differ\" title=\"Permanent link\"><\/a><\/h3>\n<\/div>\n<h2><a href=\"https:\/\/realpython.com\/python-parallel-processing\/?utm_source=realpython&#038;utm_medium=rss\">Read the full article at https:\/\/realpython.com\/python-parallel-processing\/ \u00bb<\/a><\/h2>\n<hr \/>\n<p><em>[ Improve Your Python With ? Python Tricks ? \u2013 Get a short &amp; sweet Python Trick delivered to your inbox every couple of days. <a href=\"https:\/\/realpython.com\/python-tricks\/?utm_source=realpython&amp;utm_medium=rss&amp;utm_campaign=footer\">&gt;&gt; Click here to learn more and see examples<\/a> ]<\/em><\/p>\n\n<p class=\"syndicated-attribution\"><figure class= \\\"wp-block-image alignnone \\\"><img src= \\\"http:\/\/itteacheritfreelance.hk\/test\/wordpress\/wp-content\/uploads\/2016\/05\/logo2-2.png\\\" alt=\\\"IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\\\"\/><figcaption>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427!<\/figcaption><\/figure>\r\n<\/br>Find A Teacher Form:\r\n<\/br>https:\/\/docs.google.com\/forms\/d\/1vREBnX5n262umf4wU5U2pyTwvk9O-JrAgblA-wH9GFQ\/viewform?edit_requested=true#responses\r\n<\/br><\/br>Email:\r\n<\/br>public1989two@gmail.com<br><br><br><br><br><br><br>\r\n<a href=www.itsec.hk style=color:#FFFFFF;>www.itsec.hk<\/a><br>\r\n<a href=\\\"www.itsec.vip\\\" style=color:#FFFFFF;>www.itsec.vip<\/a><br>\r\n<a href=\\\"www.itseceu.uk\\\" style=color:#FFFFFF;>www.itseceu.uk<\/a><br><\/p>","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>In this tutorial, you&#8217;ll take a deep dive into parallel processing in Python. You&#8217;ll learn about a few traditional and several novel ways of sidestepping the global interpreter lock (GIL) to achieve genuine shared-memory parallelism of your CPU-bound tasks.<\/p>\n<\/div>","protected":false},"author":2055,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"slim_seo":{"title":"Bypassing the GIL for Parallel Processing in Python - ITTeacherITFreelance.hk","description":"In this tutorial, you'll take a deep dive into parallel processing in Python. You'll learn about a few traditional and several novel ways of sidestepping the gl"},"footnotes":""},"categories":[10700],"tags":[],"_links":{"self":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329502"}],"collection":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/2055"}],"replies":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=329502"}],"version-history":[{"count":1,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329502\/revisions"}],"predecessor-version":[{"id":329503,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329502\/revisions\/329503"}],"wp:attachment":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=329502"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=329502"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=329502"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}