{"id":1758,"date":"2024-08-11T15:15:18","date_gmt":"2024-08-11T09:45:18","guid":{"rendered":"https:\/\/geekpython.in\/?p=1758"},"modified":"2024-08-11T15:15:20","modified_gmt":"2024-08-11T09:45:20","slug":"gil-become-optional-in-python","status":"publish","type":"post","link":"https:\/\/geekpython.in\/gil-become-optional-in-python","title":{"rendered":"GIL Become Optional in Python 3.13"},"content":{"rendered":"\n<p><strong>GIL<\/strong> or <strong>Global Interpreter Lock<\/strong> can be disabled in Python version 3.13. This is currently experimental.<\/p>\n\n\n\n<p>What is GIL? It is a mechanism used by the CPython interpreter to ensure that only one thread executes the Python bytecode at a time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">An Experimental Feature<\/h2>\n\n\n\n<p>Python 3.13 brings major new features compared to Python 3.12 and one of them is free-threaded mode, which disables the Global Interpreter Lock, allowing threads to run more concurrently.<\/p>\n\n\n\n<p>This is an experimental feature and if you want to try it, you can download the beta version of Python 3.13 from <a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/www.python.org\/downloads\/release\/python-3130b3\/\">here<\/a>.<\/p>\n\n\n\n<p>At the time of installation, check the option &#8220;free threaded binaries(experimental)&#8221; to get the feature in Python.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Making GIL Optional in Python 3.13<\/h2>\n\n\n\n<p>The GIL will be disabled when you configure the Python with the <code>--disable-gil<\/code> option which is nothing but a build configuration (free threading build) at the time of installation.<\/p>\n\n\n\n<p>This will allow optionally enabling and disabling GIL using the environment variable <code>PYTHON_GIL<\/code> which can be set to <code>1<\/code> and <code>0<\/code> respectively.<\/p>\n\n\n\n<p>It will also provide a command-line option <code>-X gil<\/code> which can also be set to <code>0<\/code> (disable) and <code>1<\/code> (enable).<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" ># v3.13\n# GIL disabled\npython3 -X gil=0 sample.py\n\n# GIL enabled\npython3 -X gil=1 sample.py<\/pre><\/div>\n\n\n\n<p>We can also check if the current interpreter is configured with the free threading build (<code>--disable-gil<\/code>) by using the following code.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import sysconfig\nprint(sysconfig.get_config_var(\"Py_GIL_DISABLED\"))<\/pre><\/div>\n\n\n\n<p>If we run this, we&#8217;ll get either <code>0<\/code> which means GIL is enabled, or <code>1<\/code> which means GIL is disabled.<\/p>\n\n\n\n<p>With this, we&#8217;ll also get a function that can be used to check if GIL is disabled in the running process.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import sys\nsys._is_gil_enabled()  # returns a boolean value<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">GIL Vs No GIL<\/h2>\n\n\n\n<p>Let&#8217;s see how the performance of multi-threaded programs will be affected when GIL is enabled and disabled.<\/p>\n\n\n\n<p>We have a simple Python program (<code>gil.py<\/code>) that computes the factorial of numbers and compares the execution time taken by single-threaded, multi-thread, and multi-process tasks. We&#8217;ll run this Python program first <strong>with GIL<\/strong> and then <strong>without GIL<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:python decode:true \" >import sys\nimport sysconfig\nimport math\nimport time\nimport threading\nimport multiprocessing\n\ndef compute_factorial(n):\n    return math.factorial(n)\n\n# Single-threaded\ndef single_threaded_compute(n):\n    for num in n:\n        compute_factorial(num)\n    print(\"Single-threaded: Factorial Computed.\")\n\n# Multi-threaded\ndef multi_threaded_compute(n):\n    threads = []\n    # Create 5 threads\n    for num in n:\n        thread = threading.Thread(target=compute_factorial, args=(num,))\n        threads.append(thread)\n        thread.start()\n\n    # Wait for all threads to complete\n    for thread in threads:\n        thread.join()\n\n    print(\"Multi-threaded: Factorial Computed.\")\n\n# Multi-process\ndef multi_processing_compute(n):\n    processes = []\n    # Create a process for each number in the list\n    for num in n:\n        process = multiprocessing.Process(target=compute_factorial, args=(num,))\n        processes.append(process)\n        process.start()\n\n    # Wait for all processes to complete\n    for process in processes:\n        process.join()\n\n    print(\"Multi-process: Factorial Computed.\")\n\ndef main():\n    # Checking Version\n    print(f\"Python version: {sys.version}\")\n\n    # GIL Status\n    status = sysconfig.get_config_var(\"Py_GIL_DISABLED\")\n    if status is None:\n        print(\"GIL cannot be disabled\")\n    if status == 0:\n        print(\"GIL is active\")\n    if status == 1:\n        print(\"GIL is disabled\")\n\n    numlist = [100000, 200000, 300000, 400000, 500000]\n\n    # Single-threaded Execution\n    start = time.time()\n    single_threaded_compute(numlist)\n    end = time.time() - start\n    print(f\"Single-threaded time taken: {end:.2f} seconds\")\n\n    # Multi-threaded Execution\n    start = time.time()\n    multi_threaded_compute(numlist)\n    end = time.time() - start\n    print(f\"Multi-threaded time taken : {end:.2f} seconds\")\n\n    # Multi-process Execution\n    start = time.time()\n    multi_processing_compute(numlist)\n    end = time.time() - start\n    print(f\"Multi-process time taken  : {end:.2f} seconds\")\n\n\nif __name__ == \"__main__\":\n    main()<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Running <code>gil.py<\/code> with GIL<\/h3>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex mark:6-7 decode:true \" >python gil.py\nPython version: 3.12.2 (tags\/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]\nGIL cannot be disabled\nSingle-threaded: Factorial Computed.\nSingle-threaded time taken: 9.04 seconds\nMulti-threaded: Factorial Computed.\nMulti-threaded time taken : 8.21 seconds\nMulti-process: Factorial Computed.\nMulti-process time taken  : 5.64 seconds<\/pre><\/div>\n\n\n\n<p>We have Python v3.12 in which there is no option to check the GIL status, so we got &#8220;GIL cannot be disabled&#8221;.<\/p>\n\n\n\n<p>The difference is not that much between the single-threaded and multi-threaded but we can see a pretty decent difference in the case of multi-process task.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Running <code>gil.py<\/code> without GIL<\/h3>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tex mark:6-7 decode:true \" >D:\/SACHIN\/Python13\/python3.13t gil.py\nPython version: 3.13.0b3 experimental free-threading build (tags\/v3.13.0b3:7b41395, Jun 27 2024, 16:17:17) [MSC v.1940 64 bit (AMD64)]\nGIL is disabled\nSingle-threaded: Factorial Computed.\nSingle-threaded time taken: 9.28 seconds\nMulti-threaded: Factorial Computed.\nMulti-threaded time taken : 4.86 seconds\nMulti-process: Factorial Computed.\nMulti-process time taken  : 6.14 seconds<\/pre><\/div>\n\n\n\n<p>This time we have a third beta version of Python 3.13 configured with free threading build and as we can see the GIL is disabled.<\/p>\n\n\n\n<p>But the most important part is we can see a massive difference in the performance of multi-threaded task and on the other side, some degradation can be seen in the performance of multi-process and single-threaded task.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83c\udfc6<strong>Other articles you might be interested in if you liked this one<\/strong><\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/threading-module-to-create-threads-in-python\">Create multi-threaded Python programs using a threading module<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/template-inheritance-in-flask\">Template inheritance in Flask<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/exec-and-eval\">Difference between exec and eval in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/tempfile-in-python\">Create temporary files and directories using tempfile module in Python<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/render-images-from-flask\">Upload and display images on the frontend using Flask<\/a>.<\/p>\n\n\n\n<p>\u2705<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/geekpython.in\/impact-of-learning-rates-on-ml-and-dl-models\">How does the learning rate affect the ML and DL models<\/a>?<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>That&#8217;s all for now<\/strong><\/p>\n\n\n\n<p><strong>Keep Coding\u270c\u270c<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>GIL or Global Interpreter Lock can be disabled in Python version 3.13. This is currently experimental. What is GIL? It is a mechanism used by the CPython interpreter to ensure that only one thread executes the Python bytecode at a time. An Experimental Feature Python 3.13 brings major new features compared to Python 3.12 and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1762,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[2],"tags":[31],"class_list":["post-1758","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python","tag-python3","entry","has-media"],"_links":{"self":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/comments?post=1758"}],"version-history":[{"count":2,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1758\/revisions"}],"predecessor-version":[{"id":1760,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/posts\/1758\/revisions\/1760"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media\/1762"}],"wp:attachment":[{"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/media?parent=1758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/categories?post=1758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/geekpython.in\/wp-json\/wp\/v2\/tags?post=1758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}