{"id":6561,"date":"2023-06-03T11:19:45","date_gmt":"2023-06-03T11:19:45","guid":{"rendered":"https:\/\/www.pythontutorial.net\/?page_id=6561"},"modified":"2023-06-03T11:19:46","modified_gmt":"2023-06-03T11:19:46","slug":"python-semaphore","status":"publish","type":"page","link":"https:\/\/www.pythontutorial.net\/python-concurrency\/python-semaphore\/","title":{"rendered":"Python Semaphore"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you will learn how to use Python Semaphore to control the number of threads that can access a shared resource simultaneously.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='introduction-to-the-python-semaphore'>Introduction to the Python Semaphore <a href=\"#introduction-to-the-python-semaphore\" class=\"anchor\" id=\"introduction-to-the-python-semaphore\" title=\"Anchor for Introduction to the Python Semaphore\">#<\/a><\/h2>\n\n\n\n<p>A Python semaphore is a synchronization primitive that allows you to control access to a shared resource. Basically, a semaphore is a counter associated with a <a href=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-threading-lock\/\">lock<\/a> that limits the number of <a href=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-threading\/\">threads<\/a> that can access a shared resource simultaneously. <\/p>\n\n\n\n<p>A semaphore helps prevent thread synchronization issues like race conditions, where multiple threads attempt to access the resource at the same time and interfere with each other&#8217;s operations.<\/p>\n\n\n\n<p>A semaphore maintains a count. When a thread wants to access the shared resource, the semaphore checks the count. <\/p>\n\n\n\n<p>If the count is greater than zero, it decreases the count and lets the thread accesses the resource. If the count is zero, the semaphore blocks the thread until the count becomes greater than zero.<\/p>\n\n\n\n<p>A semaphore has two main operations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Acquire: the acquire operation checks the count and decrement it if it is greater than zero. If the count is zero, the semaphore will block the thread until another thread releases the semaphore.<\/li>\n\n\n\n<li>Release: the release operation increments the counts that allow other threads to acquire it.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id='using-a-python-semaphore'>Using a Python semaphore <a href=\"#using-a-python-semaphore\" class=\"anchor\" id=\"using-a-python-semaphore\" title=\"Anchor for Using a Python semaphore\">#<\/a><\/h2>\n\n\n\n<p>To use semaphore, you follow these steps:<\/p>\n\n\n\n<p>First, import the <code>threading<\/code> module:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> threading<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, create a <code>Semaphore<\/code> object and specify the number of threads that can acquire it at the same time:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">semaphore = threading.Semaphore(<span class=\"hljs-number\">3<\/span>)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, we create a <code>Semaphore<\/code> object that only allows up to three threads to acquire it at the same time.<\/p>\n\n\n\n<p>Third, acquire a semaphore from a thread by calling the <code>acquire()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">semaphore.acquire()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If the semaphore count is zero, the thread will wait until another thread releases the semaphore. Once having the semaphore, you can execute a critical section of code.<\/p>\n\n\n\n<p>Finally, release a semaphore after running the critical section of code by calling the <code>release()<\/code> method:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">semaphore.release()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>To ensure a semaphore is properly acquired and released, even if <a href=\"https:\/\/www.pythontutorial.net\/python-oop\/python-exceptions\/\">exceptions<\/a> occur during running the critical section of a code, you can use the <code>with<\/code> statement:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">with<\/span> semaphore:\n    <span class=\"hljs-comment\"># Code within this block has acquired the semaphore<\/span>\n\n    <span class=\"hljs-comment\"># Perform operations on the shared resource<\/span>\n    <span class=\"hljs-comment\"># ...<\/span>\n    \n<span class=\"hljs-comment\"># The semaphore is released outside the with block<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The <code>with<\/code> statement acquire and release the semaphore automatically, making your code less error-prone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id='python-semaphore-example'>Python semaphore example <a href=\"#python-semaphore-example\" class=\"anchor\" id=\"python-semaphore-example\" title=\"Anchor for Python semaphore example\">#<\/a><\/h2>\n\n\n\n<p>The following example illustrates how to use the semaphore to limit the max number of concurrent downloads to three using multithreading in Python:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> threading\n<span class=\"hljs-keyword\">import<\/span> urllib.request\n\nMAX_CONCURRENT_DOWNLOADS = <span class=\"hljs-number\">3<\/span>\nsemaphore = threading.Semaphore(MAX_CONCURRENT_DOWNLOADS)\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">download<\/span><span class=\"hljs-params\">(url)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">with<\/span> semaphore:\n        print(<span class=\"hljs-string\">f\"Downloading <span class=\"hljs-subst\">{url}<\/span>...\"<\/span>)\n        \n        response = urllib.request.urlopen(url)\n        data = response.read()\n        \n        print(<span class=\"hljs-string\">f\"Finished downloading <span class=\"hljs-subst\">{url}<\/span>\"<\/span>)\n\n        <span class=\"hljs-keyword\">return<\/span> data\n\n        \n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    <span class=\"hljs-comment\"># URLs to download<\/span>\n    urls = &#91;\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc791.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc792.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc793.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc794.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc795.txt'<\/span>,\n    ]\n\n    <span class=\"hljs-comment\"># Create threads for each download<\/span>\n    threads = &#91;]\n    <span class=\"hljs-keyword\">for<\/span> url <span class=\"hljs-keyword\">in<\/span> urls:\n        thread = threading.Thread(target=download, args=(url,))\n        threads.append(thread)\n        thread.start()\n\n    <span class=\"hljs-comment\"># Wait for all threads to complete<\/span>\n    <span class=\"hljs-keyword\">for<\/span> thread <span class=\"hljs-keyword\">in<\/span> threads:\n        thread.join()\n\n\n<span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    main()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Downloading https:\/\/www.ietf.org\/rfc\/rfc791.txt...\nDownloading https:\/\/www.ietf.org\/rfc\/rfc792.txt...\nDownloading https:\/\/www.ietf.org\/rfc\/rfc793.txt...\nFinished downloading https:\/\/www.ietf.org\/rfc\/rfc792.txt\nDownloading https:\/\/www.ietf.org\/rfc\/rfc794.txt...\nFinished downloading https:\/\/www.ietf.org\/rfc\/rfc791.txt\nDownloading https:\/\/www.ietf.org\/rfc\/rfc795.txt...\nFinished downloading https:\/\/www.ietf.org\/rfc\/rfc793.txt\nFinished downloading https:\/\/www.ietf.org\/rfc\/rfc794.txt\nFinished downloading https:\/\/www.ietf.org\/rfc\/rfc795.txt<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The output shows that only a maximum of three threads can download at the same time: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Downloading https:\/\/www.ietf.org\/rfc\/rfc791.txt...\nDownloading https:\/\/www.ietf.org\/rfc\/rfc792.txt...\nDownloading https:\/\/www.ietf.org\/rfc\/rfc793.txt...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Once the number of threads reaches three, the next thread needs to wait for the semaphore to be released by another thread.<\/p>\n\n\n\n<p>For example, the following shows that thread #2 completed and released the semaphore, and the next thread start downloading the URL <code>https:\/\/www.ietf.org\/rfc\/rfc794.txt<\/code><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">Finished downloading https:\/\/www.ietf.org\/rfc\/rfc792.txt\nDownloading https:\/\/www.ietf.org\/rfc\/rfc794.txt...<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>How the program works.<\/p>\n\n\n\n<p>First, import the threading and <code>urlib.request<\/code> modules:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import<\/span> threading\n<span class=\"hljs-keyword\">import<\/span> urllib.request<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Second, create a Semaphore object to control the number of threads that can download simultaneously at the same time to three:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\">MAX_CONCURRENT_DOWNLOADS = <span class=\"hljs-number\">3<\/span>\nsemaphore = threading.Semaphore(MAX_CONCURRENT_DOWNLOADS)<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Third, define the <code>download()<\/code> function that downloads from a URL. The download function acquires and releases the semaphore using the with statement. It also uses the <code>urllib.request<\/code> module to download data from a URL:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">download<\/span><span class=\"hljs-params\">(url)<\/span>:<\/span>\n    <span class=\"hljs-keyword\">with<\/span> semaphore:\n        print(<span class=\"hljs-string\">f\"Downloading <span class=\"hljs-subst\">{url}<\/span>...\"<\/span>)\n        \n        response = urllib.request.urlopen(url)\n        data = response.read()\n        \n        print(<span class=\"hljs-string\">f\"Finished downloading <span class=\"hljs-subst\">{url}<\/span>\"<\/span>)\n\n        <span class=\"hljs-keyword\">return<\/span> data<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Fourth, define the <code>main()<\/code> function that creates five threads based on a URL list and starts them to download data:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">()<\/span>:<\/span>\n    <span class=\"hljs-comment\"># URLs to download<\/span>\n    urls = &#91;\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc791.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc792.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc793.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc794.txt'<\/span>,\n        <span class=\"hljs-string\">'https:\/\/www.ietf.org\/rfc\/rfc795.txt'<\/span>,\n    ]\n\n    <span class=\"hljs-comment\"># Create threads for each download<\/span>\n    threads = &#91;]\n    <span class=\"hljs-keyword\">for<\/span> url <span class=\"hljs-keyword\">in<\/span> urls:\n        thread = threading.Thread(target=download, args=(url,))\n        threads.append(thread)\n        thread.start()\n\n    <span class=\"hljs-comment\"># Wait for all threads to complete<\/span>\n    <span class=\"hljs-keyword\">for<\/span> thread <span class=\"hljs-keyword\">in<\/span> threads:\n        thread.join()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Finally, call the <code>main()<\/code> function in the if __name__ == &#8216;__main__&#8217; section:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Python\" data-shcb-language-slug=\"python\"><span><code class=\"hljs language-python\"><span class=\"hljs-keyword\">if<\/span> __name__ == <span class=\"hljs-string\">'__main__'<\/span>:\n    main()<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Python<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">python<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\" id='summary'>Summary <a href=\"#summary\" class=\"anchor\" id=\"summary\" title=\"Anchor for Summary\">#<\/a><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use Python semaphore to control the number of threads that can access a shared resource simultaneously.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"6561\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-semaphore\/\"\n\t\t\t\tdata-post-title=\"Python Semaphore\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"6561\"\n\t\t\t\tdata-post-url=\"https:\/\/www.pythontutorial.net\/python-concurrency\/python-semaphore\/\"\n\t\t\t\tdata-post-title=\"Python Semaphore\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\t\t\t<input type=\"button\" name=\"wth-submit\" class=\"wth-btn wth-btn-submit\" id=\"wth-submit\" \/>\n\t\t\t<input type=\"button\" class=\"wth-btn wth-btn-cancel\" value=\"Cancel\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you will learn how to use Python Semaphore to control the number of threads that can access a shared resource simultaneously. Introduction to the Python Semaphore # A Python semaphore is a synchronization primitive that allows you to control access to a shared resource. Basically, a semaphore is a counter associated [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":4104,"menu_order":10,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-6561","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6561","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/comments?post=6561"}],"version-history":[{"count":0,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/6561\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/pages\/4104"}],"wp:attachment":[{"href":"https:\/\/www.pythontutorial.net\/wp-json\/wp\/v2\/media?parent=6561"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}