{"id":4881,"date":"2022-03-28T18:43:48","date_gmt":"2022-03-28T10:43:48","guid":{"rendered":"https:\/\/egonlin.com\/?p=4881"},"modified":"2022-04-03T16:41:47","modified_gmt":"2022-04-03T08:41:47","slug":"%e7%ac%ac%e5%85%ad%e7%af%87%ef%bc%9a%e5%a4%9a%e7%ba%bf%e7%a8%8b%ef%bc%88%e6%93%8d%e4%bd%9c%e7%af%87%ef%bc%89","status":"publish","type":"post","link":"https:\/\/egonlin.com\/?p=4881","title":{"rendered":"\u7b2c\u516d\u7bc7\uff1a\u591a\u7ebf\u7a0b\uff08\u64cd\u4f5c\u7bc7\uff09"},"content":{"rendered":"<h1>\u591a\u7ebf\u7a0b\uff08\u5b9e\u64cd\uff09<\/h1>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps33.jpg'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps33.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<h2>\u4e00\u3001threading\u6a21\u5757\u4ecb\u7ecd<\/h2>\n<p>multiprocess\u6a21\u5757\u7684\u5b8c\u5168\u6a21\u4eff\u4e86threading\u6a21\u5757\u7684\u63a5\u53e3\uff0c\u4e8c\u8005\u5728\u4f7f\u7528\u5c42\u9762\uff0c\u6709\u5f88\u5927\u7684\u76f8\u4f3c\u6027\uff0c\u56e0\u800c\u4e0d\u518d\u8be6\u7ec6\u4ecb\u7ecd<\/p>\n<p><a href=\"\u5b98\u7f51\u94fe\u63a5\uff1ahttps:\/\/docs.python.org\/3\/library\/threading.html?highlight=threading#\">*\u5b98\u7f51\u94fe\u63a5*<em>\uff1ahttps:\/\/docs.python.org\/3\/library\/threading.html?highlight=threading#<\/em><\/a><\/p>\n<h2>\u4e8c\u3001\u5f00\u542f\u7ebf\u7a0b\u7684\u4e24\u79cd\u65b9\u5f0f<\/h2>\n<p>\u65b9\u5f0f\u4e00<\/p>\n<pre><code class=\"language-python\">#\u65b9\u5f0f\u4e00\nfrom threading import Thread\nimport time\ndef sayhi(name):\n    time.sleep(2)\n    print(&#039;%s say hello&#039; %name)\n\nif __name__ == &#039;__main__&#039;:\n    t=Thread(target=sayhi,args=(&#039;egon&#039;,))\n    t.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b&#039;)<\/code><\/pre>\n<p>\u65b9\u5f0f\u4e8c<\/p>\n<pre><code class=\"language-python\">#\u65b9\u5f0f\u4e8c\nfrom threading import Thread\nimport time\nclass Sayhi(Thread):\n    def __init__(self,name):\n        super().__init__()\n        self.name=name\n    def run(self):\n        time.sleep(2)\n        print(&#039;%s say hello&#039; % self.name)\n\nif __name__ == &#039;__main__&#039;:\n    t = Sayhi(&#039;egon&#039;)\n    t.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b&#039;)<\/code><\/pre>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps34.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps34.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<h2>\u4e09\u3001<strong><em>*\u5728\u4e00\u4e2a\u8fdb\u7a0b\u4e0b\u5f00\u542f\u591a\u4e2a\u7ebf\u7a0b\u4e0e\u5728\u4e00\u4e2a\u8fdb\u7a0b\u4e0b\u5f00\u542f\u591a\u4e2a\u5b50\u8fdb\u7a0b\u7684\u533a\u522b*<\/em><\/strong><\/h2>\n<p>1 \u8c01\u7684\u5f00\u542f\u901f\u5ea6\u5feb<\/p>\n<pre><code class=\"language-python\">from threading import Thread\nfrom multiprocessing import Process\nimport os\n\ndef work():\n    print(&#039;hello&#039;)\n\nif __name__ == &#039;__main__&#039;:\n    #\u5728\u4e3b\u8fdb\u7a0b\u4e0b\u5f00\u542f\u7ebf\u7a0b\n    t=Thread(target=work)\n    t.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b&#039;)\n    &#039;&#039;&#039;\n    \u6253\u5370\u7ed3\u679c:\n    hello\n    \u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b\n    &#039;&#039;&#039;\n\n    #\u5728\u4e3b\u8fdb\u7a0b\u4e0b\u5f00\u542f\u5b50\u8fdb\u7a0b\n    t=Process(target=work)\n    t.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b&#039;)\n    &#039;&#039;&#039;\n    \u6253\u5370\u7ed3\u679c:\n    \u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b\n    hello\n    &#039;&#039;&#039;<\/code><\/pre>\n<p>2 \u7785\u4e00\u7785pid<\/p>\n<pre><code class=\"language-python\">from threading import Thread\nfrom multiprocessing import Process\nimport os\n\ndef work():\n    print(&#039;hello&#039;,os.getpid())\n\nif __name__ == &#039;__main__&#039;:\n    #part1:\u5728\u4e3b\u8fdb\u7a0b\u4e0b\u5f00\u542f\u591a\u4e2a\u7ebf\u7a0b,\u6bcf\u4e2a\u7ebf\u7a0b\u90fd\u8ddf\u4e3b\u8fdb\u7a0b\u7684pid\u4e00\u6837\n    t1=Thread(target=work)\n    t2=Thread(target=work)\n    t1.start()\n    t2.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0bpid&#039;,os.getpid())\n\n    #part2:\u5f00\u591a\u4e2a\u8fdb\u7a0b,\u6bcf\u4e2a\u8fdb\u7a0b\u90fd\u6709\u4e0d\u540c\u7684pid\n    p1=Process(target=work)\n    p2=Process(target=work)\n    p1.start()\n    p2.start()\n    print(&#039;\u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0bpid&#039;,os.getpid())<\/code><\/pre>\n<p>3 \u540c\u4e00\u8fdb\u7a0b\u5185\u7684\u7ebf\u7a0b\u5171\u4eab\u8be5\u8fdb\u7a0b\u7684\u6570\u636e\uff1f<\/p>\n<pre><code class=\"language-python\">from  threading import Thread\nfrom multiprocessing import Process\nimport os\ndef work():\n    global n\n    n=0\n\nif __name__ == &#039;__main__&#039;:\n    # n=100\n    # p=Process(target=work)\n    # p.start()\n    # p.join()\n    # print(&#039;\u4e3b&#039;,n) #\u6beb\u65e0\u7591\u95ee\u5b50\u8fdb\u7a0bp\u5df2\u7ecf\u5c06\u81ea\u5df1\u7684\u5168\u5c40\u7684n\u6539\u6210\u4e860,\u4f46\u6539\u7684\u4ec5\u4ec5\u662f\u5b83\u81ea\u5df1\u7684,\u67e5\u770b\u7236\u8fdb\u7a0b\u7684n\u4ecd\u7136\u4e3a100\n\n    n=1\n    t=Thread(target=work)\n    t.start()\n    t.join()\n    print(&#039;\u4e3b&#039;,n) #\u67e5\u770b\u7ed3\u679c\u4e3a0,\u56e0\u4e3a\u540c\u4e00\u8fdb\u7a0b\u5185\u7684\u7ebf\u7a0b\u4e4b\u95f4\u5171\u4eab\u8fdb\u7a0b\u5185\u7684\u6570\u636e<\/code><\/pre>\n<h2>\u56db\u3001\u7ec3\u4e60<\/h2>\n<p>\u7ec3\u4e60\u4e00\uff1a<\/p>\n<p>\u591a\u7ebf\u7a0b\u5e76\u53d1\u7684socket\u670d\u52a1\u7aef<\/p>\n<pre><code class=\"language-python\"># -*- coding: UTF-8 -*-\n#!\/usr\/bin\/env python3\n\nimport multiprocessing\nimport threading\n\nimport socket\ns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\ns.bind((&#039;127.0.0.1&#039;,8080))\ns.listen(5)\n\ndef action(conn):\n    while True:\n        data=conn.recv(1024)\n        print(data)\n        conn.send(data.upper())\n\nif __name__ == &#039;__main__&#039;:\n\n    while True:\n        conn,addr=s.accept()\n\n        p=threading.Thread(target=action,args=(conn,))\n        p.start()<\/code><\/pre>\n<p>\u5ba2\u6237\u7aef<\/p>\n<pre><code class=\"language-python\"># -*- coding: UTF-8 -*-\n#!\/usr\/bin\/env python3\n\nimport socket\n\ns=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\ns.connect((&#039;127.0.0.1&#039;,8080))\n\nwhile True:\n    msg=input(&#039;&gt;&gt;: &#039;).strip()\n    if not msg:continue\n\n    s.send(msg.encode(&#039;utf-8&#039;))\n    data=s.recv(1024)\n    print(data)<\/code><\/pre>\n<p>\u7ec3\u4e60\u4e8c\uff1a\u4e09\u4e2a\u4efb\u52a1\uff0c\u4e00\u4e2a\u63a5\u6536\u7528\u6237\u8f93\u5165\uff0c\u4e00\u4e2a\u5c06\u7528\u6237\u8f93\u5165\u7684\u5185\u5bb9\u683c\u5f0f\u5316\u6210\u5927\u5199\uff0c\u4e00\u4e2a\u5c06\u683c\u5f0f\u5316\u540e\u7684\u7ed3\u679c\u5b58\u5165\u6587\u4ef6<\/p>\n<pre><code class=\"language-python\">from threading import Thread\nmsg_l=[]\nformat_l=[]\ndef talk():\n    while True:\n        msg=input(&#039;&gt;&gt;: &#039;).strip()\n        if not msg:continue\n        msg_l.append(msg)\n\ndef format_msg():\n    while True:\n        if msg_l:\n            res=msg_l.pop()\n            format_l.append(res.upper())\n\ndef save():\n    while True:\n        if format_l:\n            with open(&#039;db.txt&#039;,&#039;a&#039;,encoding=&#039;utf-8&#039;) as f:\n                res=format_l.pop()\n                f.write(&#039;%s\\n&#039; %res)\n\nif __name__ == &#039;__main__&#039;:\n    t1=Thread(target=talk)\n    t2=Thread(target=format_msg)\n    t3=Thread(target=save)\n    t1.start()\n    t2.start()\n    t3.start()<\/code><\/pre>\n<h2>\u4e94\u3001\u7ebf\u7a0b\u76f8\u5173\u7684\u5176\u4ed6\u65b9\u6cd5<\/h2>\n<pre><code class=\"language-python\">Thread\u5b9e\u4f8b\u5bf9\u8c61\u7684\u65b9\u6cd5\n  # isAlive(): \u8fd4\u56de\u7ebf\u7a0b\u662f\u5426\u6d3b\u52a8\u7684\u3002\n  # getName(): \u8fd4\u56de\u7ebf\u7a0b\u540d\u3002\n  # setName(): \u8bbe\u7f6e\u7ebf\u7a0b\u540d\u3002\n\nthreading\u6a21\u5757\u63d0\u4f9b\u7684\u4e00\u4e9b\u65b9\u6cd5\uff1a\n  # threading.currentThread(): \u8fd4\u56de\u5f53\u524d\u7684\u7ebf\u7a0b\u53d8\u91cf\u3002\n  # threading.enumerate(): \u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6b63\u5728\u8fd0\u884c\u7684\u7ebf\u7a0b\u7684list\u3002\u6b63\u5728\u8fd0\u884c\u6307\u7ebf\u7a0b\u542f\u52a8\u540e\u3001\u7ed3\u675f\u524d\uff0c\u4e0d\u5305\u62ec\u542f\u52a8\u524d\u548c\u7ec8\u6b62\u540e\u7684\u7ebf\u7a0b\u3002\n  # threading.activeCount(): \u8fd4\u56de\u6b63\u5728\u8fd0\u884c\u7684\u7ebf\u7a0b\u6570\u91cf\uff0c\u4e0elen(threading.enumerate())\u6709\u76f8\u540c\u7684\u7ed3\u679c\u3002\nfrom threading import Thread\nimport threading\nfrom multiprocessing import Process\nimport os\n\ndef work():\n    import time\n    time.sleep(3)\n    print(threading.current_thread().getName())\n\nif __name__ == &#039;__main__&#039;:\n    #\u5728\u4e3b\u8fdb\u7a0b\u4e0b\u5f00\u542f\u7ebf\u7a0b\n    t=Thread(target=work)\n    t.start()\n\n    print(threading.current_thread().getName())\n    print(threading.current_thread()) #\u4e3b\u7ebf\u7a0b\n    print(threading.enumerate()) #\u8fde\u540c\u4e3b\u7ebf\u7a0b\u5728\u5185\u6709\u4e24\u4e2a\u8fd0\u884c\u7684\u7ebf\u7a0b\n    print(threading.active_count())\n    print(&#039;\u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b&#039;)\n\n    &#039;&#039;&#039;\n    \u6253\u5370\u7ed3\u679c:\n    MainThread\n    &lt;_MainThread(MainThread, started 140735268892672)&gt;\n    [&lt;_MainThread(MainThread, started 140735268892672)&gt;, &lt;Thread(Thread-1, started 123145307557888)&gt;]\n    \u4e3b\u7ebf\u7a0b\/\u4e3b\u8fdb\u7a0b\n    Thread-1\n    &#039;&#039;&#039;<\/code><\/pre>\n<p>\u4e3b\u7ebf\u7a0b\u7b49\u5f85\u5b50\u7ebf\u7a0b\u7ed3\u675f<\/p>\n<pre><code class=\"language-python\">from threading import Thread\nimport time\ndef sayhi(name):\n    time.sleep(2)\n    print(&#039;%s say hello&#039; %name)\n\nif __name__ == &#039;__main__&#039;:\n    t=Thread(target=sayhi,args=(&#039;egon&#039;,))\n    t.start()\n    t.join()\n    print(&#039;\u4e3b\u7ebf\u7a0b&#039;)\n    print(t.is_alive())\n    &#039;&#039;&#039;\n    egon say hello\n    \u4e3b\u7ebf\u7a0b\n    False\n    &#039;&#039;&#039;<\/code><\/pre>\n<h2>\u516d\u3001\u5b88\u62a4\u8fdb\u7a0b<\/h2>\n<p><strong><em>*\u65e0\u8bba\u662f\u8fdb\u7a0b\u8fd8\u662f\u7ebf\u7a0b\uff0c\u90fd\u9075\u5faa\uff1a\u5b88\u62a4xxx\u4f1a\u7b49\u5f85\u4e3bxxx\u8fd0\u884c\u5b8c\u6bd5\u540e\u88ab\u9500\u6bc1*<\/em><\/strong><\/p>\n<p><strong><em>*\u9700\u8981\u5f3a\u8c03\u7684\u662f\uff1a\u8fd0\u884c\u5b8c\u6bd5\u5e76\u975e\u7ec8\u6b62\u8fd0\u884c*<\/em><\/strong><\/p>\n<p>*#1.\u5bf9\u4e3b\u8fdb\u7a0b\u6765\u8bf4\uff0c\u8fd0\u884c\u5b8c\u6bd5\u6307\u7684\u662f\u4e3b\u8fdb\u7a0b\u4ee3\u7801\u8fd0\u884c\u5b8c\u6bd5<strong><br \/>\n<\/strong><br \/>\n*<em>#2.\u5bf9\u4e3b\u7ebf\u7a0b\u6765\u8bf4\uff0c\u8fd0\u884c\u5b8c\u6bd5\u6307\u7684\u662f\u4e3b\u7ebf\u7a0b\u6240\u5728\u7684\u8fdb\u7a0b\u5185\u6240\u6709\u975e\u5b88\u62a4\u7ebf\u7a0b\u7edf\u7edf\u8fd0\u884c\u5b8c\u6bd5\uff0c\u4e3b\u7ebf\u7a0b\u624d\u7b97\u8fd0\u884c\u5b8c\u6bd5<\/em><\/p>\n<p><strong><em>*\u8be6\u7ec6\u89e3\u91ca\uff1a*<\/em><\/strong><\/p>\n<pre><code class=\"language-python\">#1 \u4e3b\u8fdb\u7a0b\u5728\u5176\u4ee3\u7801\u7ed3\u675f\u540e\u5c31\u5df2\u7ecf\u7b97\u8fd0\u884c\u5b8c\u6bd5\u4e86\uff08\u5b88\u62a4\u8fdb\u7a0b\u5728\u6b64\u65f6\u5c31\u88ab\u56de\u6536\uff09,\u7136\u540e\u4e3b\u8fdb\u7a0b\u4f1a\u4e00\u76f4\u7b49\u975e\u5b88\u62a4\u7684\u5b50\u8fdb\u7a0b\u90fd\u8fd0\u884c\u5b8c\u6bd5\u540e\u56de\u6536\u5b50\u8fdb\u7a0b\u7684\u8d44\u6e90(\u5426\u5219\u4f1a\u4ea7\u751f\u50f5\u5c38\u8fdb\u7a0b)\uff0c\u624d\u4f1a\u7ed3\u675f\uff0c\n\n#2 \u4e3b\u7ebf\u7a0b\u5728\u5176\u4ed6\u975e\u5b88\u62a4\u7ebf\u7a0b\u8fd0\u884c\u5b8c\u6bd5\u540e\u624d\u7b97\u8fd0\u884c\u5b8c\u6bd5\uff08\u5b88\u62a4\u7ebf\u7a0b\u5728\u6b64\u65f6\u5c31\u88ab\u56de\u6536\uff09\u3002\u56e0\u4e3a\u4e3b\u7ebf\u7a0b\u7684\u7ed3\u675f\u610f\u5473\u7740\u8fdb\u7a0b\u7684\u7ed3\u675f\uff0c\u8fdb\u7a0b\u6574\u4f53\u7684\u8d44\u6e90\u90fd\u5c06\u88ab\u56de\u6536\uff0c\u800c\u8fdb\u7a0b\u5fc5\u987b\u4fdd\u8bc1\u975e\u5b88\u62a4\u7ebf\u7a0b\u90fd\u8fd0\u884c\u5b8c\u6bd5\u540e\u624d\u80fd\u7ed3\u675f\u3002\nfrom threading import Thread\nimport time\ndef sayhi(name):\n    time.sleep(2)\n    print(&#039;%s say hello&#039; %name)\n\nif __name__ == &#039;__main__&#039;:\n    t=Thread(target=sayhi,args=(&#039;egon&#039;,))\n    t.setDaemon(True) #\u5fc5\u987b\u5728t.start()\u4e4b\u524d\u8bbe\u7f6e\n    t.start()\n\n    print(&#039;\u4e3b\u7ebf\u7a0b&#039;)\n    print(t.is_alive())\n    &#039;&#039;&#039;\n    \u4e3b\u7ebf\u7a0b\n    True\n    &#039;&#039;&#039;<\/code><\/pre>\n<p>\u8ff7\u60d1\u4eba\u7684\u4f8b\u5b50<\/p>\n<pre><code class=\"language-python\">from threading import Thread\nimport time\ndef foo():\n    print(123)\n    time.sleep(1)\n    print(&quot;end123&quot;)\n\ndef bar():\n    print(456)\n    time.sleep(3)\n    print(&quot;end456&quot;)\n\nt1=Thread(target=foo)\nt2=Thread(target=bar)\n\nt1.daemon=True\nt1.start()\nt2.start()\nprint(&quot;main-------&quot;)<\/code><\/pre>\n<h2>\u4e03\u3001Python GIL(Global Interpreter Lock)<\/h2>\n<h3>1\u3001\u4ecb\u7ecd<\/h3>\n<p><em>&#8221;&#8217;<strong><br \/>\n<\/strong>\u5b9a\u4e49\uff1a<strong><br \/>\n<\/strong>In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple<\/em> *<br \/>\n*<em>native threads from executing Python bytecodes at once. This lock is necessary mainly<\/em> *<\/p>\n<p><strong>because CPython\u2019s memory management is not thread-safe. (However, since the GIL<em> <\/em><br \/>\n<\/strong>exists, other features have grown to depend on the guarantees that it enforces.)<strong><br \/>\n<\/strong>&#8221;&#8217;*<em><br \/>\n<\/em>\u7ed3\u8bba\uff1a\u5728Cpython\u89e3\u91ca\u5668\u4e2d\uff0c\u540c\u4e00\u4e2a\u8fdb\u7a0b\u4e0b\u5f00\u542f\u7684\u591a\u7ebf\u7a0b\uff0c\u540c\u4e00\u65f6\u523b\u53ea\u80fd\u6709\u4e00\u4e2a\u7ebf\u7a0b\u6267\u884c\uff0c\u65e0\u6cd5\u5229\u7528\u591a\u6838\u4f18\u52bf<\/p>\n<p>\u9996\u5148\u9700\u8981\u660e\u786e\u7684\u4e00\u70b9\u662f <strong><em>\\<\/em>GIL***<em> \u5e76\u4e0d\u662f Python \u7684\u7279\u6027\uff0c\u5b83\u662f\u5728\u5b9e\u73b0Python\u89e3\u6790\u5668(CPython)\u65f6\u6240\u5f15\u5165\u7684\u4e00\u4e2a\u6982\u5ff5\u3002\u5c31\u597d\u6bd4 C++ \u662f\u4e00\u5957\u8bed\u8a00\uff08\u8bed\u6cd5\uff09\u6807\u51c6\uff0c\u4f46\u662f\u53ef\u4ee5\u7528\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u6765\u7f16\u8bd1\u6210\u53ef\u6267\u884c\u4ee3\u7801\u3002\u6709\u540d\u7684\u7f16\u8bd1\u5668\uff0c\u4f8b\u5982\uff1aGCC\uff0cINTEL C++\uff0cVisual C++\u7b49\u3002Python\u4e5f\u4e00\u6837\uff0c\u540c\u6837\u4e00\u6bb5\u4ee3\u7801\u53ef\u4ee5\u901a\u8fc7CPython\uff0cPyPy\uff0cPsyco\u7b49\u4e0d\u540c\u7684Python\u6267\u884c\u73af\u5883\u6765\u6267\u884c\u3002\u50cf\u5176\u4e2d\u7684JPython\u5c31\u6ca1\u6709 GIL \u3002\u7136\u800c\u56e0\u4e3a CPython \u662f\u5927\u90e8\u5206\u73af\u5883\u4e0b\u9ed8\u8ba4\u7684Python\u6267\u884c\u73af\u5883\u3002\u6240\u4ee5\u5728\u5f88\u591a\u4eba\u7684\u6982\u5ff5\u91cc CPython \u5c31\u662f Python \uff0c\u4e5f\u5c31\u60f3\u5f53\u7136\u7684\u628a <\/em><\/strong>*GIL**** \u5f52\u7ed3\u4e3aPython\u8bed\u8a00\u7684\u7f3a\u9677\u3002\u6240\u4ee5\u8fd9\u91cc\u8981\u5148\u660e\u786e\u4e00\u70b9\uff1a GIL \u5e76\u4e0d\u662f Python \u7684\u7279\u6027\uff0cPython\u5b8c\u5168\u53ef\u4ee5\u4e0d\u4f9d\u8d56\u4e8eGIL\u3002<\/p>\n<h3>2\u3001GIL\u4ecb\u7ecd<\/h3>\n<p>GIL\u672c\u8d28\u5c31\u662f\u4e00\u628a\u4e92\u65a5\u9501\uff0c\u65e2\u7136\u662f\u4e92\u65a5\u9501\uff0c\u6240\u6709\u4e92\u65a5\u9501\u7684\u672c\u8d28\u90fd\u4e00\u6837\uff0c\u90fd\u662f\u5c06\u5e76\u53d1\u8fd0\u884c\u53d8\u6210\u4e32\u884c\uff0c\u4ee5\u6b64\u6765\u63a7\u5236\u540c\u4e00\u65f6\u95f4\u5185\u5171\u4eab\u6570\u636e\u53ea\u80fd\u88ab\u4e00\u4e2a\u4efb\u52a1\u6240\u4fee\u6539\uff0c\u8fdb\u800c\u4fdd\u8bc1\u6570\u636e\u5b89\u5168\u3002<\/p>\n<p>\u53ef\u4ee5\u80af\u5b9a\u7684\u4e00\u70b9\u662f\uff1a\u4fdd\u62a4\u4e0d\u540c\u7684\u6570\u636e\u7684\u5b89\u5168\uff0c\u5c31\u5e94\u8be5\u52a0\u4e0d\u540c\u7684\u9501\u3002<\/p>\n<p>\u8981\u60f3\u4e86\u89e3GIL\uff0c\u9996\u5148\u786e\u5b9a\u4e00\u70b9\uff1a\u6bcf\u6b21\u6267\u884cpython\u7a0b\u5e8f\uff0c\u90fd\u4f1a\u4ea7\u751f\u4e00\u4e2a\u72ec\u7acb\u7684\u8fdb\u7a0b\u3002\u4f8b\u5982python test.py\uff0cpython aaa.py\uff0cpython bbb.py\u4f1a\u4ea7\u751f3\u4e2a\u4e0d\u540c\u7684python\u8fdb\u7a0b<\/p>\n<pre><code class=\"language-python\">&#039;&#039;&#039;\n#\u9a8c\u8bc1python test.py\u53ea\u4f1a\u4ea7\u751f\u4e00\u4e2a\u8fdb\u7a0b\n#test.py\u5185\u5bb9\nimport os,time\nprint(os.getpid())\ntime.sleep(1000)\n&#039;&#039;&#039;\npython3 test.py \n#\u5728windows\u4e0b\ntasklist |findstr python\n\n#\u5728linux\u4e0b\nps aux |grep python<\/code><\/pre>\n<p>\u5728\u4e00\u4e2apython\u7684\u8fdb\u7a0b\u5185\uff0c\u4e0d\u4ec5\u6709test.py\u7684\u4e3b\u7ebf\u7a0b\u6216\u8005\u7531\u8be5\u4e3b\u7ebf\u7a0b\u5f00\u542f\u7684\u5176\u4ed6\u7ebf\u7a0b\uff0c\u8fd8\u6709\u89e3\u91ca\u5668\u5f00\u542f\u7684\u5783\u573e\u56de\u6536\u7b49\u89e3\u91ca\u5668\u7ea7\u522b\u7684\u7ebf\u7a0b\uff0c\u603b\u4e4b\uff0c\u6240\u6709\u7ebf\u7a0b\u90fd\u8fd0\u884c\u5728\u8fd9\u4e00\u4e2a\u8fdb\u7a0b\u5185\uff0c\u6beb\u65e0\u7591\u95ee<\/p>\n<p>*#1 \u6240\u6709\u6570\u636e\u90fd\u662f\u5171\u4eab\u7684\uff0c\u8fd9\u5176\u4e2d\uff0c\u4ee3\u7801\u4f5c\u4e3a\u4e00\u79cd\u6570\u636e\u4e5f\u662f\u88ab\u6240\u6709\u7ebf\u7a0b\u5171\u4eab\u7684\uff08test.py\u7684\u6240\u6709\u4ee3\u7801\u4ee5\u53caCpython\u89e3\u91ca\u5668\u7684\u6240\u6709\u4ee3\u7801\uff09<strong><br \/>\n<em>\u4f8b\u5982\uff1atest.py\u5b9a\u4e49\u4e00\u4e2a\u51fd\u6570work\uff08\u4ee3\u7801\u5185\u5bb9\u5982\u4e0b\u56fe\uff09\uff0c\u5728\u8fdb\u7a0b\u5185\u6240\u6709\u7ebf\u7a0b\u90fd\u80fd\u8bbf\u95ee\u5230work\u7684\u4ee3\u7801\uff0c\u4e8e\u662f\u6211\u4eec\u53ef\u4ee5\u5f00\u542f\u4e09\u4e2a\u7ebf\u7a0b\u7136\u540etarget\u90fd\u6307\u5411\u8be5\u4ee3\u7801\uff0c\u80fd\u8bbf\u95ee\u5230\u610f\u5473\u7740\u5c31\u662f\u53ef\u4ee5\u6267\u884c\u3002<\/em><br \/>\n<\/strong><br \/>\n*<em>#2 \u6240\u6709\u7ebf\u7a0b\u7684\u4efb\u52a1\uff0c\u90fd\u9700\u8981\u5c06\u4efb\u52a1\u7684\u4ee3\u7801\u5f53\u505a\u53c2\u6570\u4f20\u7ed9\u89e3\u91ca\u5668\u7684\u4ee3\u7801\u53bb\u6267\u884c\uff0c\u5373\u6240\u6709\u7684\u7ebf\u7a0b\u8981\u60f3\u8fd0\u884c\u81ea\u5df1\u7684\u4efb\u52a1\uff0c\u9996\u5148\u9700\u8981\u89e3\u51b3\u7684\u662f\u80fd\u591f\u8bbf\u95ee\u5230\u89e3\u91ca\u5668\u7684\u4ee3\u7801\u3002<\/em><\/p>\n<p>\u7efc\u4e0a\uff1a<\/p>\n<p>\u5982\u679c\u591a\u4e2a\u7ebf\u7a0b\u7684target=work\uff0c\u90a3\u4e48\u6267\u884c\u6d41\u7a0b\u662f<\/p>\n<p>\u591a\u4e2a\u7ebf\u7a0b\u5148\u8bbf\u95ee\u5230\u89e3\u91ca\u5668\u7684\u4ee3\u7801\uff0c\u5373\u62ff\u5230\u6267\u884c\u6743\u9650\uff0c\u7136\u540e\u5c06target\u7684\u4ee3\u7801\u4ea4\u7ed9\u89e3\u91ca\u5668\u7684\u4ee3\u7801\u53bb\u6267\u884c<\/p>\n<p>\u89e3\u91ca\u5668\u7684\u4ee3\u7801\u662f\u6240\u6709\u7ebf\u7a0b\u5171\u4eab\u7684\uff0c\u6240\u4ee5\u5783\u573e\u56de\u6536\u7ebf\u7a0b\u4e5f\u53ef\u80fd\u8bbf\u95ee\u5230\u89e3\u91ca\u5668\u7684\u4ee3\u7801\u800c\u53bb\u6267\u884c\uff0c\u8fd9\u5c31\u5bfc\u81f4\u4e86\u4e00\u4e2a\u95ee\u9898:\u5bf9\u4e8e\u540c\u4e00\u4e2a\u6570\u636e100\uff0c\u53ef\u80fd\u7ebf\u7a0b1\u6267\u884cx=100\u7684\u540c\u65f6\uff0c\u800c\u5783\u573e\u56de\u6536\u6267\u884c\u7684\u662f\u56de\u6536100\u7684\u64cd\u4f5c\uff0c\u89e3\u51b3\u8fd9\u79cd\u95ee\u9898\u6ca1\u6709\u4ec0\u4e48\u9ad8\u660e\u7684\u65b9\u6cd5\uff0c\u5c31\u662f\u52a0\u9501\u5904\u7406\uff0c\u5982\u4e0b\u56fe\u7684GIL\uff0c\u4fdd\u8bc1python\u89e3\u91ca\u5668\u540c\u4e00\u65f6\u95f4\u53ea\u80fd\u6267\u884c\u4e00\u4e2a\u4efb\u52a1\u7684\u4ee3\u7801<\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps35.jpg'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps35.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<h3>3\u3001GIL\u4e0eLock<\/h3>\n<p><strong>GIL\u4fdd\u62a4\u7684\u662f\u89e3\u91ca\u5668\u7ea7\u7684\u6570\u636e\uff0c\u4fdd\u62a4\u7528\u6237\u81ea\u5df1\u7684\u6570\u636e\u5219\u9700\u8981\u81ea\u5df1\u52a0\u9501\u5904\u7406\uff0c\u5982\u4e0b\u56fe<\/strong><\/p>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps36.jpg'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps36.jpg\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<h3>4\u3001GIL\u4e0e\u591a\u7ebf\u7a0b<\/h3>\n<p>\u6709\u4e86GIL\u7684\u5b58\u5728\uff0c\u540c\u4e00\u65f6\u523b\u540c\u4e00\u8fdb\u7a0b\u4e2d\u53ea\u6709\u4e00\u4e2a\u7ebf\u7a0b\u88ab\u6267\u884c<\/p>\n<p>\u542c\u5230\u8fd9\u91cc\uff0c\u6709\u7684\u540c\u5b66\u7acb\u9a6c\u8d28\u95ee\uff1a\u8fdb\u7a0b\u53ef\u4ee5\u5229\u7528\u591a\u6838\uff0c\u4f46\u662f\u5f00\u9500\u5927\uff0c\u800cpython\u7684\u591a\u7ebf\u7a0b\u5f00\u9500\u5c0f\uff0c\u4f46\u5374\u65e0\u6cd5\u5229\u7528\u591a\u6838\u4f18\u52bf\uff0c\u4e5f\u5c31\u662f\u8bf4python\u6ca1\u7528\u4e86\uff0cphp\u624d\u662f\u6700\u725b\u903c\u7684\u8bed\u8a00\uff1f<\/p>\n<p>\u522b\u7740\u6025\u554a\uff0c\u8001\u5a18\u8fd8\u6ca1\u8bb2\u5b8c\u5462\u3002<\/p>\n<p>\u8981\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6211\u4eec\u9700\u8981\u5728\u51e0\u4e2a\u70b9\u4e0a\u8fbe\u6210\u4e00\u81f4\uff1a<\/p>\n<p><em>#1. cpu\u5230\u5e95\u662f\u7528\u6765\u505a\u8ba1\u7b97\u7684\uff0c\u8fd8\u662f\u7528\u6765\u505aI\/O\u7684\uff1f<strong><br \/>\n<\/strong><br \/>\n<strong>#2. \u591acpu\uff0c\u610f\u5473\u7740\u53ef\u4ee5\u6709\u591a\u4e2a\u6838\u5e76\u884c\u5b8c\u6210\u8ba1\u7b97\uff0c\u6240\u4ee5\u591a\u6838\u63d0\u5347\u7684\u662f\u8ba1\u7b97\u6027\u80fd<\/strong><br \/>\n<strong><br \/>\n<\/strong>#3. \u6bcf\u4e2acpu\u4e00\u65e6\u9047\u5230I\/O\u963b\u585e\uff0c\u4ecd\u7136\u9700\u8981\u7b49\u5f85\uff0c\u6240\u4ee5\u591a\u6838\u5bf9I\/O\u64cd\u4f5c\u6ca1\u4ec0\u4e48\u7528\u5904<\/em> <\/p>\n<p>\u4e00\u4e2a\u5de5\u4eba\u76f8\u5f53\u4e8ecpu\uff0c\u6b64\u65f6\u8ba1\u7b97\u76f8\u5f53\u4e8e\u5de5\u4eba\u5728\u5e72\u6d3b\uff0cI\/O\u963b\u585e\u76f8\u5f53\u4e8e\u4e3a\u5de5\u4eba\u5e72\u6d3b\u63d0\u4f9b\u6240\u9700\u539f\u6750\u6599\u7684\u8fc7\u7a0b\uff0c\u5de5\u4eba\u5e72\u6d3b\u7684\u8fc7\u7a0b\u4e2d\u5982\u679c\u6ca1\u6709\u539f\u6750\u6599\u4e86\uff0c\u5219\u5de5\u4eba\u5e72\u6d3b\u7684\u8fc7\u7a0b\u9700\u8981\u505c\u6b62\uff0c\u76f4\u5230\u7b49\u5f85\u539f\u6750\u6599\u7684\u5230\u6765\u3002<\/p>\n<p>\u5982\u679c\u4f60\u7684\u5de5\u5382\u5e72\u7684\u5927\u591a\u6570\u4efb\u52a1\u90fd\u8981\u6709\u51c6\u5907\u539f\u6750\u6599\u7684\u8fc7\u7a0b\uff08I\/O\u5bc6\u96c6\u578b\uff09\uff0c\u90a3\u4e48\u4f60\u6709\u518d\u591a\u7684\u5de5\u4eba\uff0c\u610f\u4e49\u4e5f\u4e0d\u5927\uff0c\u8fd8\u4e0d\u5982\u4e00\u4e2a\u4eba\uff0c\u5728\u7b49\u6750\u6599\u7684\u8fc7\u7a0b\u4e2d\u8ba9\u5de5\u4eba\u53bb\u5e72\u522b\u7684\u6d3b\uff0c\u53cd\u8fc7\u6765\u8bb2\uff0c\u5982\u679c\u4f60\u7684\u5de5\u5382\u539f\u6750\u6599\u90fd\u9f50\u5168\uff0c\u90a3\u5f53\u7136\u662f\u5de5\u4eba\u8d8a\u591a\uff0c\u6548\u7387\u8d8a\u9ad8<\/p>\n<p>\u7ed3\u8bba\uff1a<\/p>\n<p>\u5bf9\u8ba1\u7b97\u6765\u8bf4\uff0ccpu\u8d8a\u591a\u8d8a\u597d\uff0c\u4f46\u662f\u5bf9\u4e8eI\/O\u6765\u8bf4\uff0c\u518d\u591a\u7684cpu\u4e5f\u6ca1\u7528<\/p>\n<p>\u5f53\u7136\u5bf9\u8fd0\u884c\u4e00\u4e2a\u7a0b\u5e8f\u6765\u8bf4\uff0c\u968f\u7740cpu\u7684\u589e\u591a\u6267\u884c\u6548\u7387\u80af\u5b9a\u4f1a\u6709\u6240\u63d0\u9ad8\uff08\u4e0d\u7ba1\u63d0\u9ad8\u5e45\u5ea6\u591a\u5927\uff0c\u603b\u4f1a\u6709\u6240\u63d0\u9ad8\uff09\uff0c\u8fd9\u662f\u56e0\u4e3a\u4e00\u4e2a\u7a0b\u5e8f\u57fa\u672c\u4e0a\u4e0d\u4f1a\u662f\u7eaf\u8ba1\u7b97\u6216\u8005\u7eafI\/O\uff0c\u6240\u4ee5\u6211\u4eec\u53ea\u80fd\u76f8\u5bf9\u7684\u53bb\u770b\u4e00\u4e2a\u7a0b\u5e8f\u5230\u5e95\u662f\u8ba1\u7b97\u5bc6\u96c6\u578b\u8fd8\u662fI\/O\u5bc6\u96c6\u578b\uff0c\u4ece\u800c\u8fdb\u4e00\u6b65\u5206\u6790python\u7684\u591a\u7ebf\u7a0b\u5230\u5e95\u6709\u65e0\u7528\u6b66\u4e4b\u5730<\/p>\n<p>*# \u5206\u6790\uff1a<strong><br \/>\n<em>\u6211\u4eec\u6709\u56db\u4e2a\u4efb\u52a1\u9700\u8981\u5904\u7406\uff0c\u5904\u7406\u65b9\u5f0f\u80af\u5b9a\u662f\u8981\u73a9\u51fa\u5e76\u53d1\u7684\u6548\u679c\uff0c\u89e3\u51b3\u65b9\u6848\u53ef\u4ee5\u662f\uff1a<\/em><br \/>\n<em>\u65b9\u6848\u4e00\uff1a\u5f00\u542f\u56db\u4e2a\u8fdb\u7a0b<\/em><br \/>\n<em>\u65b9\u6848\u4e8c\uff1a\u4e00\u4e2a\u8fdb\u7a0b\u4e0b\uff0c\u5f00\u542f\u56db\u4e2a\u7ebf\u7a0b<\/em><br \/>\n<\/strong><br \/>\n<strong># \u5355\u6838\u60c5\u51b5\u4e0b\uff0c\u5206\u6790\u7ed3\u679c:<em> <\/em><br \/>\n<em>\u5982\u679c\u56db\u4e2a\u4efb\u52a1\u662f\u8ba1\u7b97\u5bc6\u96c6\u578b\uff0c\u6ca1\u6709\u591a\u6838\u6765\u5e76\u884c\u8ba1\u7b97\uff0c\u65b9\u6848\u4e00\u5f92\u589e\u4e86\u521b\u5efa\u8fdb\u7a0b\u7684\u5f00\u9500\uff0c\u65b9\u6848\u4e8c\u80dc<\/em><br \/>\n<em>\u5982\u679c\u56db\u4e2a\u4efb\u52a1\u662fI\/O\u5bc6\u96c6\u578b\uff0c\u65b9\u6848\u4e00\u521b\u5efa\u8fdb\u7a0b\u7684\u5f00\u9500\u5927\uff0c\u4e14\u8fdb\u7a0b\u7684\u5207\u6362\u901f\u5ea6\u8fdc\u4e0d\u5982\u7ebf\u7a0b\uff0c\u65b9\u6848\u4e8c\u80dc<\/em><br \/>\n<\/strong><br \/>\n<strong># \u591a\u6838\u60c5\u51b5\u4e0b\uff0c\u5206\u6790\u7ed3\u679c\uff1a<\/strong><br \/>\n<em>\u5982\u679c\u56db\u4e2a\u4efb\u52a1\u662f\u8ba1\u7b97\u5bc6\u96c6\u578b\uff0c\u591a\u6838\u610f\u5473\u7740\u5e76\u884c\u8ba1\u7b97\uff0c\u5728python\u4e2d\u4e00\u4e2a\u8fdb\u7a0b\u4e2d\u540c\u4e00\u65f6\u523b\u53ea\u6709\u4e00\u4e2a\u7ebf\u7a0b\u6267\u884c\u7528\u4e0d\u4e0a\u591a\u6838\uff0c\u65b9\u6848\u4e00\u80dc<\/em><br \/>\n<em>\u5982\u679c\u56db\u4e2a\u4efb\u52a1\u662fI\/O\u5bc6\u96c6\u578b\uff0c\u518d\u591a\u7684\u6838\u4e5f\u89e3\u51b3\u4e0d\u4e86I\/O\u95ee\u9898\uff0c\u65b9\u6848\u4e8c\u80dc<\/em><br \/>\n<strong><br \/>\n* *<br \/>\n<\/strong># \u7ed3\u8bba\uff1a\u73b0\u5728\u7684\u8ba1\u7b97\u673a\u57fa\u672c\u4e0a\u90fd\u662f\u591a\u6838\uff0cpython\u5bf9\u4e8e\u8ba1\u7b97\u5bc6\u96c6\u578b\u7684\u4efb\u52a1\u5f00\u591a\u7ebf\u7a0b\u7684\u6548\u7387\u5e76\u4e0d\u80fd\u5e26\u6765\u591a\u5927\u6027\u80fd\u4e0a\u7684\u63d0\u5347\uff0c\u751a\u81f3\u4e0d\u5982\u4e32\u884c(\u6ca1\u6709\u5927\u91cf\u5207\u6362)\uff0c\u4f46\u662f\uff0c\u5bf9\u4e8eIO\u5bc6\u96c6\u578b\u7684\u4efb\u52a1\u6548\u7387\u8fd8\u662f\u6709\u663e\u8457\u63d0\u5347\u7684\u3002*<\/p>\n<h3>5\u3001\u591a\u7ebf\u7a0b\u6027\u80fd\u6d4b\u8bd5<\/h3>\n<p>\u8ba1\u7b97\u5bc6\u96c6\u578b\uff1a\u591a\u8fdb\u7a0b\u6548\u7387\u9ad8<\/p>\n<pre><code class=\"language-python\">from multiprocessing import Process\nfrom threading import Thread\nimport os,time\ndef work():\n    res=0\n    for i in range(100000000):\n        res*=i\n\nif __name__ == &#039;__main__&#039;:\n    l=[]\n    print(os.cpu_count()) #\u672c\u673a\u4e3a4\u6838\n    start=time.time()\n    for i in range(4):\n        p=Process(target=work) #\u8017\u65f65s\u591a\n        p=Thread(target=work) #\u8017\u65f618s\u591a\n        l.append(p)\n        p.start()\n    for p in l:\n        p.join()\n    stop=time.time()\n    print(&#039;run time is %s&#039; %(stop-start))<\/code><\/pre>\n<p>I\/O\u5bc6\u96c6\u578b\uff1a\u591a\u7ebf\u7a0b\u6548\u7387\u9ad8<\/p>\n<pre><code class=\"language-bash\">from multiprocessing import Process\nfrom threading import Thread\nimport threading\nimport os,time\ndef work():\n    time.sleep(2)\n    print(&#039;===&gt;&#039;)\n\nif __name__ == &#039;__main__&#039;:\n    l=[]\n    print(os.cpu_count()) #\u672c\u673a\u4e3a4\u6838\n    start=time.time()\n    for i in range(400):\n        # p=Process(target=work) #\u8017\u65f612s\u591a,\u5927\u90e8\u5206\u65f6\u95f4\u8017\u8d39\u5728\u521b\u5efa\u8fdb\u7a0b\u4e0a\n        p=Thread(target=work) #\u8017\u65f62s\u591a\n        l.append(p)\n        p.start()\n    for p in l:\n        p.join()\n    stop=time.time()\n    print(&#039;run time is %s&#039; %(stop-start))<\/code><\/pre>\n<p>\u5e94\u7528\uff1a<\/p>\n<p>\u591a\u7ebf\u7a0b\u7528\u4e8eIO\u5bc6\u96c6\u578b\uff0c\u5982\uff1asocket\uff0c\u722c\u866b\uff0cweb \u591a\u8fdb\u7a0b\u7528\u4e8e\u8ba1\u7b97\u5bc6\u96c6\u578b\uff0c\u5982\uff1a\u91d1\u878d\u5206\u6790<\/p>\n<h3>6\u3001CPU \u548c GIL \u5fc5\u987b\u90fd\u5177\u5907\u624d\u53ef\u4ee5\u6267\u884c\u4ee3\u7801<\/h3>\n<p>\u62ff\u5230 CPU \u6743\u9650 -&gt; \u62ff\u5230 GIL \u89e3\u91ca\u5668\u9501 -&gt; \u6267\u884c\u4ee3\u7801<\/p>\n<p>\u5728 Python 3.2 \u4e4b\u540e GIL \u6709\u4e86\u65b0\u7684\u5b9e\u73b0\uff0c\u76ee\u7684\u662f\u4e3a\u4e86\u89e3\u51b3 That GIL Thrashing \u95ee\u9898\uff0c\u8fd9\u662fAntoine Pitrou \u7684\u529f\u52b3<\/p>\n<h3>7\u3001GIL \u89e3\u91ca\u5668\u9501\u4f1a\u5728\u4e24\u79cd\u60c5\u51b5\u4e0b\u91ca\u653e<\/h3>\n<h4>1.\u4e3b\u52a8\u91ca\u653e<\/h4>\n<p>\u9047\u5230 IO \u64cd\u4f5c\u6216\u8005\u5206\u914d\u7684 CPU \u65f6\u95f4\u7247\u5230\u65f6\u95f4\u4e86\u3002<\/p>\n<p>\u6ce8\u610f\uff0cGIL\u5b58\u5728\u7684\u610f\u4e49\u5728\u4e8e\u7ef4\u62a4\u7ebf\u7a0b\u5b89\u5168\uff0cx=10\u6d89\u53ca\u5230IO\u64cd\u4f5c\uff0c\u5982\u679c\u4e5f\u88ab\u5f53\u6210\u666e\u901a\u7684IO\u64cd\u4f5c\uff0c\u4e3b\u52a8\u4ea4\u51faGIL\uff0c\u90a3\u4e48\u4e00\u5b9a\u4f1a\u51fa\u73b0\u6570\u636e\u4e0d\u5b89\u5168\u95ee\u9898\uff0c\u6240\u4ee5x=10\u4e00\u5b9a\u662f\u88ab\u533a\u5206\u5bf9\u5f85\u4e86\u3002<\/p>\n<p>\u81f3\u4e8ex=10\u5982\u4f55\u5b9e\u73b0\u7684\u88ab\u533a\u5206\u5bf9\u5f85\uff0c\u8fd9\u5176\u5b9e\u5f88\u597d\u7406\u89e3\uff0c\u4efb\u4f55\u7684io\u64cd\u4f5c\u90fd\u662f\u5411\u64cd\u4f5c\u7cfb\u7edf\u53d1\u9001\u7cfb\u7edf\u8c03\u7528\uff0c\u5373\u8c03\u7528\u64cd\u4f5c\u7cfb\u7edf\u7684\u67d0\u4e00\u63a5\u53e3\u5b9e\u73b0\u7684\uff0c\u6bd4\u5982\u53d8\u91cf\u8d4b\u503c\u64cd\u4f5c\u80af\u5b9a\u662f\u8c03\u7528\u4e86\u4e00\u79cd\u63a5\u53e3\uff0c\u6587\u4ef6\u8bfb\u5199\u64cd\u4f5c\u80af\u5b9a\u4e5f\u662f\u8c03\u7528\u4e86\u4e00\u79cd\u63a5\u53e3\uff0c\u7f51\u7edcio\u4e5f\u662f\u8c03\u7528\u4e86\u67d0\u4e00\u79cd\u63a5\u53e3\uff0c\u8fd9\u5c31\u7ed9\u533a\u5206\u5bf9\u5f85\u63d0\u4f9b\u4e86\u5b9e\u73b0\u7684\u4f9d\u636e\uff0c\u5373\u53d8\u91cf\u8d4b\u503c\u64cd\u4f5c\u5e76\u4e0d\u5c5e\u4e8e\u4e3b\u52a8\u91ca\u653e\u7684\u8303\u7574\uff0c\u8fd9\u6837GIL\u5728\u7ebf\u7a0b\u5b89\u5168\u65b9\u9762\u624d\u4f1a\u6709\u6240\u4f5c\u4e3a\u3002<\/p>\n<h4>2.\u88ab\u52a8\u91ca\u653e<\/h4>\n<p>python3.2\u4e4b\u540e\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf<\/p>\n<p>\/<em> Python\/ceval.c <\/em>\/<em><br \/>\n<\/em>&#8230;<em><br \/>\n<\/em>static volatile int gil_drop_request = 0;<\/p>\n<p>\u6ce8\u610f\u5f53\u53ea\u6709\u4e00\u4e2a\u7ebf\u7a0b\u65f6\uff0c\u8be5\u7ebf\u7a0b\u4f1a\u4e00\u76f4\u8fd0\u884c\uff0c\u4e0d\u4f1a\u91ca\u653eGIL\uff0c\u5f53\u6709\u591a\u4e2a\u7ebf\u7a0b\u65f6<\/p>\n<p>\u4f8b\u5982thead1\uff0cthread2<\/p>\n<p>\u5982\u679cthread1\u4e00\u76f4\u6ca1\u6709\u4e3b\u52a8\u91ca\u653e\u6389GIL\uff0c\u90a3\u80af\u5b9a\u4e0d\u4f1a\u8ba9\u4ed6\u4e00\u76f4\u8fd0\u884c\u4e0b\u53bb\u554a<\/p>\n<p>\u5b9e\u9645\u4e0a\u5728thread1\u8fd0\u884c\u7684\u8fc7\u7a0b\u65f6\uff0cthread2\u5c31\u4f1a\u6267\u884c\u4e00\u4e2acv_wait(gil,TIMEOUT)\u7684\u51fd\u6570<\/p>\n<p>\uff08\u9ed8\u8ba4TIMEOUT\u503c\u4e3a5milliseconds\uff0c\u4f46\u662f\u53ef\u4ee5\u4fee\u6539\uff09\uff0c\u4e00\u65e6\u5230\u4e86\u65f6\u95f4\uff0c\u5c31\u4f1a\u5c06\u5168\u5c40\u53d8\u91cf<\/p>\n<p>gil_drop_request = 1;\uff0c\u7ebf\u7a0bthread1\u5c31\u4f1a\u88ab\u5f3a\u5236\u91ca\u653eGIL\uff0c\u7136\u540e\u7ebf\u7a0bthread2\u5f00\u59cb\u8fd0\u884c\u5e76<\/p>\n<p>\u8fd4\u56de\u4e00\u4e2aack\u7ed9\u7ebf\u7a0bthread1\uff0c\u7ebf\u7a0bthread1\u5f00\u59cb\u8c03\u7528cv_wait(gil,TIMEOUT)<\/p>\n<p>\u8fd9\u7bc7\u6587\u7ae0\u900f\u5f7b\u7684\u5256\u6790\u4e86 GIL \u5bf9 Python \u591a\u7ebf\u7a0b\u7684\u5f71\u54cd\uff0c\u5f3a\u70c8\u63a8\u8350\u770b\u4e00\u4e0b\uff1a<a href=\"http:\/\/www.dabeaz.com\/python\/UnderstandingGIL.pdf\">http:\/\/www.dabeaz.com\/python\/UnderstandingGIL.pdf<\/a><\/p>\n<h2>\u516b\u3001\u540c\u6b65\u9501<\/h2>\n<p>\u4e09\u4e2a\u9700\u8981\u6ce8\u610f\u7684\u70b9\uff1a*<br \/>\n<strong>#1.\u7ebf\u7a0b\u62a2\u7684\u662fGIL\u9501\uff0cGIL\u9501\u76f8\u5f53\u4e8e\u6267\u884c\u6743\u9650\uff0c\u62ff\u5230\u6267\u884c\u6743\u9650\u540e\u624d\u80fd\u62ff\u5230\u4e92\u65a5\u9501Lock\uff0c\u5176\u4ed6\u7ebf\u7a0b\u4e5f\u53ef\u4ee5\u62a2\u5230GIL\uff0c\u4f46\u5982\u679c\u53d1\u73b0Lock\u4ecd\u7136\u6ca1\u6709\u88ab\u91ca\u653e\u5219\u963b\u585e\uff0c\u5373\u4fbf\u662f\u62ff\u5230\u6267\u884c\u6743\u9650GIL\u4e5f\u8981\u7acb\u523b\u4ea4\u51fa\u6765<\/strong><br \/>\n<strong><br \/>\n<\/strong>#2.join\u662f\u7b49\u5f85\u6240\u6709\uff0c\u5373\u6574\u4f53\u4e32\u884c\uff0c\u800c\u9501\u53ea\u662f\u9501\u4f4f\u4fee\u6539\u5171\u4eab\u6570\u636e\u7684\u90e8\u5206\uff0c\u5373\u90e8\u5206\u4e32\u884c\uff0c\u8981\u60f3\u4fdd\u8bc1\u6570\u636e\u5b89\u5168\u7684\u6839\u672c\u539f\u7406\u5728\u4e8e\u8ba9\u5e76\u53d1\u53d8\u6210\u4e32\u884c\uff0cjoin\u4e0e\u4e92\u65a5\u9501\u90fd\u53ef\u4ee5\u5b9e\u73b0\uff0c\u6beb\u65e0\u7591\u95ee\uff0c\u4e92\u65a5\u9501\u7684\u90e8\u5206\u4e32\u884c\u6548\u7387\u8981\u66f4\u9ad8<strong><br \/>\n<\/strong><br \/>\n*<em>#3. \u4e00\u5b9a\u8981\u770b\u672c\u5c0f\u8282\u6700\u540e\u7684GIL\u4e0e\u4e92\u65a5\u9501\u7684\u7ecf\u5178\u5206\u6790<\/em><\/p>\n<p><strong><em>*GIL VS Lock*<\/em><\/strong><\/p>\n<p><strong><em>*\u673a\u667a\u7684\u540c\u5b66\u53ef\u80fd\u4f1a\u95ee\u5230\u8fd9\u4e2a\u95ee\u9898\uff0c\u5c31\u662f\u65e2\u7136\u4f60\u4e4b\u524d\u8bf4\u8fc7\u4e86\uff0cPython\u5df2\u7ecf\u6709\u4e00\u4e2aGIL\u6765\u4fdd\u8bc1\u540c\u4e00\u65f6\u95f4\u53ea\u80fd\u6709\u4e00\u4e2a\u7ebf\u7a0b\u6765\u6267\u884c\u4e86\uff0c\u4e3a\u4ec0\u4e48\u8fd9\u91cc\u8fd8\u9700\u8981lock?*<\/em><\/strong><\/p>\n<p><strong><em>*\u9996\u5148\u6211\u4eec\u9700\u8981\u8fbe\u6210\u5171\u8bc6\uff1a\u9501\u7684\u76ee\u7684\u662f\u4e3a\u4e86\u4fdd\u62a4\u5171\u4eab\u7684\u6570\u636e\uff0c\u540c\u4e00\u65f6\u95f4\u53ea\u80fd\u6709\u4e00\u4e2a\u7ebf\u7a0b\u6765\u4fee\u6539\u5171\u4eab\u7684\u6570\u636e*<\/em><\/strong><\/p>\n<p><strong><em>*\u7136\u540e\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u7ed3\u8bba\uff1a\u4fdd\u62a4\u4e0d\u540c\u7684\u6570\u636e\u5c31\u5e94\u8be5\u52a0\u4e0d\u540c\u7684\u9501\u3002*<\/em><\/strong><\/p>\n<p><strong><em>*\u6700\u540e\uff0c\u95ee\u9898\u5c31\u5f88\u660e\u6717\u4e86\uff0cGIL \u4e0eLock\u662f\u4e24\u628a\u9501\uff0c\u4fdd\u62a4\u7684\u6570\u636e\u4e0d\u4e00\u6837\uff0c\u524d\u8005\u662f\u89e3\u91ca\u5668\u7ea7\u522b\u7684\uff08\u5f53\u7136\u4fdd\u62a4\u7684\u5c31\u662f\u89e3\u91ca\u5668\u7ea7\u522b\u7684\u6570\u636e\uff0c\u6bd4\u5982\u5783\u573e\u56de\u6536\u7684\u6570\u636e\uff09\uff0c\u540e\u8005\u662f\u4fdd\u62a4\u7528\u6237\u81ea\u5df1\u5f00\u53d1\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u6570\u636e\uff0c\u5f88\u660e\u663eGIL\u4e0d\u8d1f\u8d23\u8fd9\u4ef6\u4e8b\uff0c\u53ea\u80fd\u7528\u6237\u81ea\u5b9a\u4e49\u52a0\u9501\u5904\u7406\uff0c\u5373Lock*<\/em><\/strong><\/p>\n<p><strong><em>*\u8fc7\u7a0b\u5206\u6790\uff1a\u6240\u6709\u7ebf\u7a0b\u62a2\u7684\u662fGIL\u9501\uff0c\u6216\u8005\u8bf4\u6240\u6709\u7ebf\u7a0b\u62a2\u7684\u662f\u6267\u884c\u6743\u9650*<\/em><\/strong><\/p>\n<p><strong><em>*\u7ebf\u7a0b1\u62a2\u5230GIL\u9501\uff0c\u62ff\u5230\u6267\u884c\u6743\u9650\uff0c\u5f00\u59cb\u6267\u884c\uff0c\u7136\u540e\u52a0\u4e86\u4e00\u628aLock\uff0c\u8fd8\u6ca1\u6709\u6267\u884c\u5b8c\u6bd5\uff0c\u5373\u7ebf\u7a0b1\u8fd8\u672a\u91ca\u653eLock\uff0c\u6709\u53ef\u80fd\u7ebf\u7a0b2\u62a2\u5230GIL\u9501\uff0c\u5f00\u59cb\u6267\u884c\uff0c\u6267\u884c\u8fc7\u7a0b\u4e2d\u53d1\u73b0Lock\u8fd8\u6ca1\u6709\u88ab\u7ebf\u7a0b1\u91ca\u653e\uff0c\u4e8e\u662f\u7ebf\u7a0b2\u8fdb\u5165\u963b\u585e\uff0c\u88ab\u593a\u8d70\u6267\u884c\u6743\u9650\uff0c\u6709\u53ef\u80fd\u7ebf\u7a0b1\u62ff\u5230GIL\uff0c\u7136\u540e\u6b63\u5e38\u6267\u884c\u5230\u91ca\u653eLock\u3002\u3002\u3002\u8fd9\u5c31\u5bfc\u81f4\u4e86\u4e32\u884c\u8fd0\u884c\u7684\u6548\u679c*<\/em><\/strong><\/p>\n<p><strong><em>*\u65e2\u7136\u662f\u4e32\u884c\uff0c\u90a3\u6211\u4eec\u6267\u884c*<\/em><\/strong><\/p>\n<p><strong><em>*t1.start()*<\/em><\/strong><\/p>\n<p><strong><em>*t1.join*<\/em><\/strong><\/p>\n<p><strong><em>*t2.start()*<\/em><\/strong><\/p>\n<p><strong><em>*t2.join()*<\/em><\/strong><\/p>\n<p><strong><em>*\u8fd9\u4e5f\u662f\u4e32\u884c\u6267\u884c\u554a\uff0c\u4e3a\u4f55\u8fd8\u8981\u52a0Lock\u5462\uff0c\u9700\u77e5join\u662f\u7b49\u5f85t1\u6240\u6709\u7684\u4ee3\u7801\u6267\u884c\u5b8c\uff0c\u76f8\u5f53\u4e8e\u9501\u4f4f\u4e86t1\u7684\u6240\u6709\u4ee3\u7801\uff0c\u800cLock\u53ea\u662f\u9501\u4f4f\u4e00\u90e8\u5206\u64cd\u4f5c\u5171\u4eab\u6570\u636e\u7684\u4ee3\u7801\u3002*<\/em><\/strong><\/p>\n<p>\u8be6\u7ec6<\/p>\n<pre><code class=\"language-python\">\u56e0\u4e3aPython\u89e3\u91ca\u5668\u5e2e\u4f60\u81ea\u52a8\u5b9a\u671f\u8fdb\u884c\u5185\u5b58\u56de\u6536\uff0c\u4f60\u53ef\u4ee5\u7406\u89e3\u4e3apython\u89e3\u91ca\u5668\u91cc\u6709\u4e00\u4e2a\u72ec\u7acb\u7684\u7ebf\u7a0b\uff0c\u6bcf\u8fc7\u4e00\u6bb5\u65f6\u95f4\u5b83\u8d77wake up\u505a\u4e00\u6b21\u5168\u5c40\u8f6e\u8be2\u770b\u770b\u54ea\u4e9b\u5185\u5b58\u6570\u636e\u662f\u53ef\u4ee5\u88ab\u6e05\u7a7a\u7684\uff0c\u6b64\u65f6\u4f60\u81ea\u5df1\u7684\u7a0b\u5e8f\u91cc\u7684\u7ebf\u7a0b\u548cpy\u89e3\u91ca\u5668\u81ea\u5df1\u7684\u7ebf\u7a0b\u662f\u5e76\u53d1\u8fd0\u884c\u7684\uff0c\u5047\u8bbe\u4f60\u7684\u7ebf\u7a0b\u5220\u9664\u4e86\u4e00\u4e2a\u53d8\u91cf\uff0cpy\u89e3\u91ca\u5668\u7684\u5783\u573e\u56de\u6536\u7ebf\u7a0b\u5728\u6e05\u7a7a\u8fd9\u4e2a\u53d8\u91cf\u7684\u8fc7\u7a0b\u4e2d\u7684clearing\u65f6\u523b\uff0c\u53ef\u80fd\u4e00\u4e2a\u5176\u5b83\u7ebf\u7a0b\u6b63\u597d\u53c8\u91cd\u65b0\u7ed9\u8fd9\u4e2a\u8fd8\u6ca1\u6765\u53ca\u5f97\u6e05\u7a7a\u7684\u5185\u5b58\u7a7a\u95f4\u8d4b\u503c\u4e86\uff0c\u7ed3\u679c\u5c31\u6709\u53ef\u80fd\u65b0\u8d4b\u503c\u7684\u6570\u636e\u88ab\u5220\u9664\u4e86\uff0c\u4e3a\u4e86\u89e3\u51b3\u7c7b\u4f3c\u7684\u95ee\u9898\uff0cpython\u89e3\u91ca\u5668\u7b80\u5355\u7c97\u66b4\u7684\u52a0\u4e86\u9501\uff0c\u5373\u5f53\u4e00\u4e2a\u7ebf\u7a0b\u8fd0\u884c\u65f6\uff0c\u5176\u5b83\u4eba\u90fd\u4e0d\u80fd\u52a8\uff0c\u8fd9\u6837\u5c31\u89e3\u51b3\u4e86\u4e0a\u8ff0\u7684\u95ee\u9898\uff0c  \u8fd9\u53ef\u4ee5\u8bf4\u662fPython\u65e9\u671f\u7248\u672c\u7684\u9057\u7559\u95ee\u9898\u3002\nfrom threading import Thread\nimport os,time\ndef work():\n    global n\n    temp=n\n    time.sleep(0.1)\n    n=temp-1\nif __name__ == &#039;__main__&#039;:\n    n=100\n    l=[]\n    for i in range(100):\n        p=Thread(target=work)\n        l.append(p)\n        p.start()\n    for p in l:\n        p.join()\n\n    print(n) #\u7ed3\u679c\u53ef\u80fd\u4e3a99<\/code><\/pre>\n<p><strong><em>*\u9501\u901a\u5e38\u88ab\u7528\u6765\u5b9e\u73b0\u5bf9\u5171\u4eab\u8d44\u6e90\u7684\u540c\u6b65\u8bbf\u95ee\u3002\u4e3a\u6bcf\u4e00\u4e2a\u5171\u4eab\u8d44\u6e90\u521b\u5efa\u4e00\u4e2aLock\u5bf9\u8c61\uff0c\u5f53\u4f60\u9700\u8981\u8bbf\u95ee\u8be5\u8d44\u6e90\u65f6\uff0c\u8c03\u7528acquire\u65b9\u6cd5\u6765\u83b7\u53d6\u9501\u5bf9\u8c61\uff08\u5982\u679c\u5176\u5b83\u7ebf\u7a0b\u5df2\u7ecf\u83b7\u5f97\u4e86\u8be5\u9501\uff0c\u5219\u5f53\u524d\u7ebf\u7a0b\u9700\u7b49\u5f85\u5176\u88ab\u91ca\u653e\uff09\uff0c\u5f85\u8d44\u6e90\u8bbf\u95ee\u5b8c\u540e\uff0c\u518d\u8c03\u7528release\u65b9\u6cd5\u91ca\u653e\u9501\uff1a*<\/em><\/strong><\/p>\n<pre><code class=\"language-python\">import threading\n\nR=threading.Lock()\n\nR.acquire()\n&#039;&#039;&#039;\n\u5bf9\u516c\u5171\u6570\u636e\u7684\u64cd\u4f5c\n&#039;&#039;&#039;\nR.release()\nfrom threading import Thread,Lock\nimport os,time\ndef work():\n    global n\n    lock.acquire()\n    temp=n\n    time.sleep(0.1)\n    n=temp-1\n    lock.release()\nif __name__ == &#039;__main__&#039;:\n    lock=Lock()\n    n=100\n    l=[]\n    for i in range(100):\n        p=Thread(target=work)\n        l.append(p)\n        p.start()\n    for p in l:\n        p.join()\n\n    print(n) #\u7ed3\u679c\u80af\u5b9a\u4e3a0\uff0c\u7531\u539f\u6765\u7684\u5e76\u53d1\u6267\u884c\u53d8\u6210\u4e32\u884c\uff0c\u727a\u7272\u4e86\u6267\u884c\u6548\u7387\u4fdd\u8bc1\u4e86\u6570\u636e\u5b89\u5168<\/code><\/pre>\n<p>GIL\u9501\u4e0e\u4e92\u65a5\u9501\u7efc\u5408\u5206\u6790\uff08\u91cd\u70b9\uff01\uff01\uff01\uff09<\/p>\n<p>\u5206\u6790\uff1a*<\/p>\n<p><em>\u3000\u3000<\/em>#1.100\u4e2a\u7ebf\u7a0b\u53bb\u62a2GIL\u9501\uff0c\u5373\u62a2\u6267\u884c\u6743\u9650<strong><br \/>\n*   *#2. \u80af\u5b9a\u6709\u4e00\u4e2a\u7ebf\u7a0b\u5148\u62a2\u5230GIL\uff08\u6682\u4e14\u79f0\u4e3a\u7ebf\u7a0b1\uff09\uff0c\u7136\u540e\u5f00\u59cb\u6267\u884c\uff0c\u4e00\u65e6\u6267\u884c\u5c31\u4f1a\u62ff\u5230lock.acquire()<\/strong><br \/>\n*   *#3. \u6781\u6709\u53ef\u80fd\u7ebf\u7a0b1\u8fd8\u672a\u8fd0\u884c\u5b8c\u6bd5\uff0c\u5c31\u6709\u53e6\u5916\u4e00\u4e2a\u7ebf\u7a0b2\u62a2\u5230GIL\uff0c\u7136\u540e\u5f00\u59cb\u8fd0\u884c\uff0c\u4f46\u7ebf\u7a0b2\u53d1\u73b0\u4e92\u65a5\u9501lock\u8fd8\u672a\u88ab\u7ebf\u7a0b1\u91ca\u653e\uff0c\u4e8e\u662f\u963b\u585e\uff0c\u88ab\u8feb\u4ea4\u51fa\u6267\u884c\u6743\u9650\uff0c\u5373\u91ca\u653eGIL*<em><br \/>\n*  <\/em>#4.\u76f4\u5230\u7ebf\u7a0b1\u91cd\u65b0\u62a2\u5230GIL\uff0c\u5f00\u59cb\u4ece\u4e0a\u6b21\u6682\u505c\u7684\u4f4d\u7f6e\u7ee7\u7eed\u6267\u884c\uff0c\u76f4\u5230\u6b63\u5e38\u91ca\u653e\u4e92\u65a5\u9501lock\uff0c\u7136\u540e\u5176\u4ed6\u7684\u7ebf\u7a0b\u518d\u91cd\u590d2 3 4\u7684\u8fc7\u7a0b*<\/p>\n<p>\u4e92\u65a5\u9501\u4e0ejoin\u7684\u533a\u522b\uff08\u91cd\u70b9\uff01\uff01\uff01\uff09<\/p>\n<pre><code class=\"language-python\">#\u4e0d\u52a0\u9501:\u5e76\u53d1\u6267\u884c,\u901f\u5ea6\u5feb,\u6570\u636e\u4e0d\u5b89\u5168\nfrom threading import current_thread,Thread,Lock\nimport os,time\ndef task():\n    global n\n    print(&#039;%s is running&#039; %current_thread().getName())\n    temp=n\n    time.sleep(0.5)\n    n=temp-1\n\nif __name__ == &#039;__main__&#039;:\n    n=100\n    lock=Lock()\n    threads=[]\n    start_time=time.time()\n    for i in range(100):\n        t=Thread(target=task)\n        threads.append(t)\n        t.start()\n    for t in threads:\n        t.join()\n\n    stop_time=time.time()\n    print(&#039;\u4e3b:%s n:%s&#039; %(stop_time-start_time,n))\n\n&#039;&#039;&#039;\nThread-1 is running\nThread-2 is running\n......\nThread-100 is running\n\u4e3b:0.5216062068939209 n:99\n&#039;&#039;&#039;\n\n#\u4e0d\u52a0\u9501:\u672a\u52a0\u9501\u90e8\u5206\u5e76\u53d1\u6267\u884c,\u52a0\u9501\u90e8\u5206\u4e32\u884c\u6267\u884c,\u901f\u5ea6\u6162,\u6570\u636e\u5b89\u5168\nfrom threading import current_thread,Thread,Lock\nimport os,time\ndef task():\n    #\u672a\u52a0\u9501\u7684\u4ee3\u7801\u5e76\u53d1\u8fd0\u884c\n    time.sleep(3)\n    print(&#039;%s start to run&#039; %current_thread().getName())\n    global n\n    #\u52a0\u9501\u7684\u4ee3\u7801\u4e32\u884c\u8fd0\u884c\n    lock.acquire()\n    temp=n\n    time.sleep(0.5)\n    n=temp-1\n    lock.release()\n\nif __name__ == &#039;__main__&#039;:\n    n=100\n    lock=Lock()\n    threads=[]\n    start_time=time.time()\n    for i in range(100):\n        t=Thread(target=task)\n        threads.append(t)\n        t.start()\n    for t in threads:\n        t.join()\n    stop_time=time.time()\n    print(&#039;\u4e3b:%s n:%s&#039; %(stop_time-start_time,n))\n\n&#039;&#039;&#039;\nThread-1 is running\nThread-2 is running\n......\nThread-100 is running\n\u4e3b:53.294203758239746 n:0\n&#039;&#039;&#039;\n\n#\u6709\u7684\u540c\u5b66\u53ef\u80fd\u6709\u7591\u95ee:\u65e2\u7136\u52a0\u9501\u4f1a\u8ba9\u8fd0\u884c\u53d8\u6210\u4e32\u884c,\u90a3\u4e48\u6211\u5728start\u4e4b\u540e\u7acb\u5373\u4f7f\u7528join,\u5c31\u4e0d\u7528\u52a0\u9501\u4e86\u554a,\u4e5f\u662f\u4e32\u884c\u7684\u6548\u679c\u554a\n#\u6ca1\u9519:\u5728start\u4e4b\u540e\u7acb\u523b\u4f7f\u7528jion,\u80af\u5b9a\u4f1a\u5c06100\u4e2a\u4efb\u52a1\u7684\u6267\u884c\u53d8\u6210\u4e32\u884c,\u6beb\u65e0\u7591\u95ee,\u6700\u7ec8n\u7684\u7ed3\u679c\u4e5f\u80af\u5b9a\u662f0,\u662f\u5b89\u5168\u7684,\u4f46\u95ee\u9898\u662f\n#start\u540e\u7acb\u5373join:\u4efb\u52a1\u5185\u7684\u6240\u6709\u4ee3\u7801\u90fd\u662f\u4e32\u884c\u6267\u884c\u7684,\u800c\u52a0\u9501,\u53ea\u662f\u52a0\u9501\u7684\u90e8\u5206\u5373\u4fee\u6539\u5171\u4eab\u6570\u636e\u7684\u90e8\u5206\u662f\u4e32\u884c\u7684\n#\u5355\u4ece\u4fdd\u8bc1\u6570\u636e\u5b89\u5168\u65b9\u9762,\u4e8c\u8005\u90fd\u53ef\u4ee5\u5b9e\u73b0,\u4f46\u5f88\u660e\u663e\u662f\u52a0\u9501\u7684\u6548\u7387\u66f4\u9ad8.\nfrom threading import current_thread,Thread,Lock\nimport os,time\ndef task():\n    time.sleep(3)\n    print(&#039;%s start to run&#039; %current_thread().getName())\n    global n\n    temp=n\n    time.sleep(0.5)\n    n=temp-1\n\nif __name__ == &#039;__main__&#039;:\n    n=100\n    lock=Lock()\n    start_time=time.time()\n    for i in range(100):\n        t=Thread(target=task)\n        t.start()\n        t.join()\n    stop_time=time.time()\n    print(&#039;\u4e3b:%s n:%s&#039; %(stop_time-start_time,n))\n\n&#039;&#039;&#039;\nThread-1 start to run\nThread-2 start to run\n......\nThread-100 start to run\n\u4e3b:350.6937336921692 n:0 #\u8017\u65f6\u662f\u591a\u4e48\u7684\u6050\u6016\n&#039;&#039;&#039;<\/code><\/pre>\n<h2>\u4e5d\u3001\u6b7b\u9501\u73b0\u8c61\u4e0e\u9012\u5f52\u9501<\/h2>\n<p>\u8fdb\u7a0b\u4e5f\u6709\u6b7b\u9501\u4e0e\u9012\u5f52\u9501\uff0c\u5728\u8fdb\u7a0b\u90a3\u91cc\u5fd8\u8bb0\u8bf4\u4e86\uff0c\u653e\u5230\u8fd9\u91cc\u4e00\u5207\u8bf4\u4e86\u989d<\/p>\n<p>\u6240\u8c13\u6b7b\u9501\uff1a \u662f\u6307\u4e24\u4e2a\u6216\u4e24\u4e2a\u4ee5\u4e0a\u7684\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5728\u6267\u884c\u8fc7\u7a0b\u4e2d\uff0c\u56e0\u4e89\u593a\u8d44\u6e90\u800c\u9020\u6210\u7684\u4e00\u79cd\u4e92\u76f8\u7b49\u5f85\u7684\u73b0\u8c61\uff0c\u82e5\u65e0\u5916\u529b\u4f5c\u7528\uff0c\u5b83\u4eec\u90fd\u5c06\u65e0\u6cd5\u63a8\u8fdb\u4e0b\u53bb\u3002\u6b64\u65f6\u79f0\u7cfb\u7edf\u5904\u4e8e\u6b7b\u9501\u72b6\u6001\u6216\u7cfb\u7edf\u4ea7\u751f\u4e86\u6b7b\u9501\uff0c\u8fd9\u4e9b\u6c38\u8fdc\u5728\u4e92\u76f8\u7b49\u5f85\u7684\u8fdb\u7a0b\u79f0\u4e3a\u6b7b\u9501\u8fdb\u7a0b\uff0c\u5982\u4e0b\u5c31\u662f\u6b7b\u9501<\/p>\n<pre><code class=\"language-python\">from threading import Thread,Lock\nimport time\nmutexA=Lock()\nmutexB=Lock()\n\nclass MyThread(Thread):\n    def run(self):\n        self.func1()\n        self.func2()\n    def func1(self):\n        mutexA.acquire()\n        print(&#039;\\033[41m%s \u62ff\u5230A\u9501\\033[0m&#039; %self.name)\n\n        mutexB.acquire()\n        print(&#039;\\033[42m%s \u62ff\u5230B\u9501\\033[0m&#039; %self.name)\n        mutexB.release()\n\n        mutexA.release()\n\n    def func2(self):\n        mutexB.acquire()\n        print(&#039;\\033[43m%s \u62ff\u5230B\u9501\\033[0m&#039; %self.name)\n        time.sleep(2)\n\n        mutexA.acquire()\n        print(&#039;\\033[44m%s \u62ff\u5230A\u9501\\033[0m&#039; %self.name)\n        mutexA.release()\n\n        mutexB.release()\n\nif __name__ == &#039;__main__&#039;:\n    for i in range(10):\n        t=MyThread()\n        t.start()\n\n&#039;&#039;&#039;\nThread-1 \u62ff\u5230A\u9501\nThread-1 \u62ff\u5230B\u9501\nThread-1 \u62ff\u5230B\u9501\nThread-2 \u62ff\u5230A\u9501\n\u7136\u540e\u5c31\u5361\u4f4f\uff0c\u6b7b\u9501\u4e86\n&#039;&#039;&#039;<\/code><\/pre>\n<p>\u89e3\u51b3\u65b9\u6cd5\uff0c\u9012\u5f52\u9501\uff0c\u5728Python\u4e2d\u4e3a\u4e86\u652f\u6301\u5728\u540c\u4e00\u7ebf\u7a0b\u4e2d\u591a\u6b21\u8bf7\u6c42\u540c\u4e00\u8d44\u6e90\uff0cpython\u63d0\u4f9b\u4e86\u53ef\u91cd\u5165\u9501RLock\u3002<\/p>\n<p>\u8fd9\u4e2aRLock\u5185\u90e8\u7ef4\u62a4\u7740\u4e00\u4e2aLock\u548c\u4e00\u4e2acounter\u53d8\u91cf\uff0ccounter\u8bb0\u5f55\u4e86acquire\u7684\u6b21\u6570\uff0c\u4ece\u800c\u4f7f\u5f97\u8d44\u6e90\u53ef\u4ee5\u88ab\u591a\u6b21require\u3002\u76f4\u5230\u4e00\u4e2a\u7ebf\u7a0b\u6240\u6709\u7684acquire\u90fd\u88abrelease\uff0c\u5176\u4ed6\u7684\u7ebf\u7a0b\u624d\u80fd\u83b7\u5f97\u8d44\u6e90\u3002\u4e0a\u9762\u7684\u4f8b\u5b50\u5982\u679c\u4f7f\u7528RLock\u4ee3\u66ffLock\uff0c\u5219\u4e0d\u4f1a\u53d1\u751f\u6b7b\u9501\uff1a<\/p>\n<p>mutexA=mutexB=threading.RLock() <em>#\u4e00\u4e2a\u7ebf\u7a0b\u62ff\u5230\u9501\uff0ccounter\u52a01,\u8be5\u7ebf\u7a0b\u5185\u53c8\u78b0\u5230\u52a0\u9501\u7684\u60c5\u51b5\uff0c\u5219counter\u7ee7\u7eed\u52a01\uff0c\u8fd9\u671f\u95f4\u6240\u6709\u5176\u4ed6\u7ebf\u7a0b\u90fd\u53ea\u80fd\u7b49\u5f85\uff0c\u7b49\u5f85\u8be5\u7ebf\u7a0b\u91ca\u653e\u6240\u6709\u9501\uff0c\u5373counter\u9012\u51cf\u52300\u4e3a\u6b62<\/em><\/p>\n<h2>\u5341\u3001\u4fe1\u53f7\u91cfSemaphore<\/h2>\n<p>\u540c\u8fdb\u7a0b\u7684\u4e00\u6837\uff0cSemaphore\u7ba1\u7406\u4e00\u4e2a\u5185\u7f6e\u7684\u8ba1\u6570\u5668\uff0c \u6bcf\u5f53\u8c03\u7528acquire()\u65f6\u5185\u7f6e\u8ba1\u6570\u5668-1\uff1b \u8c03\u7528release() \u65f6\u5185\u7f6e\u8ba1\u6570\u5668+1\uff1b \u8ba1\u6570\u5668\u4e0d\u80fd\u5c0f\u4e8e0\uff1b\u5f53\u8ba1\u6570\u5668\u4e3a0\u65f6\uff0cacquire()\u5c06\u963b\u585e\u7ebf\u7a0b\u76f4\u5230\u5176\u4ed6\u7ebf\u7a0b\u8c03\u7528release()\u3002<\/p>\n<p>\u5b9e\u4f8b\uff1a(\u540c\u65f6\u53ea\u67095\u4e2a\u7ebf\u7a0b\u53ef\u4ee5\u83b7\u5f97semaphore,\u5373\u53ef\u4ee5\u9650\u5236\u6700\u5927\u8fde\u63a5\u6570\u4e3a5)\uff1a<\/p>\n<pre><code class=\"language-python\">from threading import Thread,Semaphore\nimport threading\nimport time\n# def func():\n#     if sm.acquire():\n#         print (threading.currentThread().getName() + &#039; get semaphore&#039;)\n#         time.sleep(2)\n#         sm.release()\ndef func():\n    sm.acquire()\n    print(&#039;%s get sm&#039; %threading.current_thread().getName())\n    time.sleep(3)\n    sm.release()\nif __name__ == &#039;__main__&#039;:\n    sm=Semaphore(5)\n    for i in range(23):\n        t=Thread(target=func)\n        t.start()<\/code><\/pre>\n<p><strong><em>*\u4e0e\u8fdb\u7a0b\u6c60\u662f\u5b8c\u5168\u4e0d\u540c\u7684\u6982\u5ff5\uff0c\u8fdb\u7a0b\u6c60Pool(4)\uff0c\u6700\u5927\u53ea\u80fd\u4ea7\u751f4\u4e2a\u8fdb\u7a0b\uff0c\u800c\u4e14\u4ece\u5934\u5230\u5c3e\u90fd\u53ea\u662f\u8fd9\u56db\u4e2a\u8fdb\u7a0b\uff0c\u4e0d\u4f1a\u4ea7\u751f\u65b0\u7684\uff0c\u800c\u4fe1\u53f7\u91cf\u662f\u4ea7\u751f\u4e00\u5806\u7ebf\u7a0b\/\u8fdb\u7a0b*<\/em><\/strong><\/p>\n<p>\u4e92\u65a5\u9501\u4e0e\u4fe1\u53f7\u91cf\u63a8\u8350\u535a\u5ba2\uff1a<a href=\"http:\/\/url.cn\/5DMsS9r\">http:\/\/url.cn\/5DMsS9r<\/a><\/p>\n<h2>\u5341\u4e00\u3001Event<\/h2>\n<p>\u540c\u8fdb\u7a0b\u7684\u4e00\u6837<\/p>\n<p>\u7ebf\u7a0b\u7684\u4e00\u4e2a\u5173\u952e\u7279\u6027\u662f\u6bcf\u4e2a\u7ebf\u7a0b\u90fd\u662f\u72ec\u7acb\u8fd0\u884c\u4e14\u72b6\u6001\u4e0d\u53ef\u9884\u6d4b\u3002\u5982\u679c\u7a0b\u5e8f\u4e2d\u7684\u5176 \u4ed6\u7ebf\u7a0b\u9700\u8981\u901a\u8fc7\u5224\u65ad\u67d0\u4e2a\u7ebf\u7a0b\u7684\u72b6\u6001\u6765\u786e\u5b9a\u81ea\u5df1\u4e0b\u4e00\u6b65\u7684\u64cd\u4f5c,\u8fd9\u65f6\u7ebf\u7a0b\u540c\u6b65\u95ee\u9898\u5c31\u4f1a\u53d8\u5f97\u975e\u5e38\u68d8\u624b\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e9b\u95ee\u9898,\u6211\u4eec\u9700\u8981\u4f7f\u7528threading\u5e93\u4e2d\u7684Event\u5bf9\u8c61\u3002 \u5bf9\u8c61\u5305\u542b\u4e00\u4e2a\u53ef\u7531\u7ebf\u7a0b\u8bbe\u7f6e\u7684\u4fe1\u53f7\u6807\u5fd7,\u5b83\u5141\u8bb8\u7ebf\u7a0b\u7b49\u5f85\u67d0\u4e9b\u4e8b\u4ef6\u7684\u53d1\u751f\u3002\u5728 \u521d\u59cb\u60c5\u51b5\u4e0b,Event\u5bf9\u8c61\u4e2d\u7684\u4fe1\u53f7\u6807\u5fd7\u88ab\u8bbe\u7f6e\u4e3a\u5047\u3002\u5982\u679c\u6709\u7ebf\u7a0b\u7b49\u5f85\u4e00\u4e2aEvent\u5bf9\u8c61, \u800c\u8fd9\u4e2aEvent\u5bf9\u8c61\u7684\u6807\u5fd7\u4e3a\u5047,\u90a3\u4e48\u8fd9\u4e2a\u7ebf\u7a0b\u5c06\u4f1a\u88ab\u4e00\u76f4\u963b\u585e\u76f4\u81f3\u8be5\u6807\u5fd7\u4e3a\u771f\u3002\u4e00\u4e2a\u7ebf\u7a0b\u5982\u679c\u5c06\u4e00\u4e2aEvent\u5bf9\u8c61\u7684\u4fe1\u53f7\u6807\u5fd7\u8bbe\u7f6e\u4e3a\u771f,\u5b83\u5c06\u5524\u9192\u6240\u6709\u7b49\u5f85\u8fd9\u4e2aEvent\u5bf9\u8c61\u7684\u7ebf\u7a0b\u3002\u5982\u679c\u4e00\u4e2a\u7ebf\u7a0b\u7b49\u5f85\u4e00\u4e2a\u5df2\u7ecf\u88ab\u8bbe\u7f6e\u4e3a\u771f\u7684Event\u5bf9\u8c61,\u90a3\u4e48\u5b83\u5c06\u5ffd\u7565\u8fd9\u4e2a\u4e8b\u4ef6, \u7ee7\u7eed\u6267\u884c<\/p>\n<pre><code class=\"language-python\">event.isSet()\uff1a\u8fd4\u56deevent\u7684\u72b6\u6001\u503c\uff1b\n\nevent.wait()\uff1a\u5982\u679c event.isSet()==False\u5c06\u963b\u585e\u7ebf\u7a0b\uff1b\n\nevent.set()\uff1a \u8bbe\u7f6eevent\u7684\u72b6\u6001\u503c\u4e3aTrue\uff0c\u6240\u6709\u963b\u585e\u6c60\u7684\u7ebf\u7a0b\u6fc0\u6d3b\u8fdb\u5165\u5c31\u7eea\u72b6\u6001\uff0c \u7b49\u5f85\u64cd\u4f5c\u7cfb\u7edf\u8c03\u5ea6\uff1b\n\nevent.clear()\uff1a\u6062\u590devent\u7684\u72b6\u6001\u503c\u4e3aFalse\u3002<\/code><\/pre>\n<p><div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps37.png'><img class=\"lazyload lazyload-style-2\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  data-original=\"https:\/\/egonlin.com\/wp-content\/uploads\/2022\/03\/wps37.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" alt=\"\" \/><\/div><\/p>\n<p>\u4f8b\u5982\uff0c\u6709\u591a\u4e2a\u5de5\u4f5c\u7ebf\u7a0b\u5c1d\u8bd5\u94fe\u63a5MySQL\uff0c\u6211\u4eec\u60f3\u8981\u5728\u94fe\u63a5\u524d\u786e\u4fddMySQL\u670d\u52a1\u6b63\u5e38\u624d\u8ba9\u90a3\u4e9b\u5de5\u4f5c\u7ebf\u7a0b\u53bb\u8fde\u63a5MySQL\u670d\u52a1\u5668\uff0c\u5982\u679c\u8fde\u63a5\u4e0d\u6210\u529f\uff0c\u90fd\u4f1a\u53bb\u5c1d\u8bd5\u91cd\u65b0\u8fde\u63a5\u3002\u90a3\u4e48\u6211\u4eec\u5c31\u53ef\u4ee5\u91c7\u7528threading.Event\u673a\u5236\u6765\u534f\u8c03\u5404\u4e2a\u5de5\u4f5c\u7ebf\u7a0b\u7684\u8fde\u63a5\u64cd\u4f5c<\/p>\n<pre><code class=\"language-python\">from threading import Thread,Event\nimport threading\nimport time,random\ndef conn_mysql():\n    count=1\n    while not event.is_set():\n        if count &gt; 3:\n            raise TimeoutError(&#039;\u94fe\u63a5\u8d85\u65f6&#039;)\n        print(&#039;&lt;%s&gt;\u7b2c%s\u6b21\u5c1d\u8bd5\u94fe\u63a5&#039; % (threading.current_thread().getName(), count))\n        event.wait(0.5)\n        count+=1\n    print(&#039;&lt;%s&gt;\u94fe\u63a5\u6210\u529f&#039; %threading.current_thread().getName())\n\ndef check_mysql():\n    print(&#039;\\033[45m[%s]\u6b63\u5728\u68c0\u67e5mysql\\033[0m&#039; % threading.current_thread().getName())\n    time.sleep(random.randint(2,4))\n    event.set()\nif __name__ == &#039;__main__&#039;:\n    event=Event()\n    conn1=Thread(target=conn_mysql)\n    conn2=Thread(target=conn_mysql)\n    check=Thread(target=check_mysql)\n\n    conn1.start()\n    conn2.start()\n    check.start()<\/code><\/pre>\n<h2>\u5341\u4e8c\u3001\u6761\u4ef6Condition\uff08\u4e86\u89e3\uff09<\/h2>\n<p>\u4f7f\u5f97\u7ebf\u7a0b\u7b49\u5f85\uff0c\u53ea\u6709\u6ee1\u8db3\u67d0\u6761\u4ef6\u65f6\uff0c\u624d\u91ca\u653en\u4e2a\u7ebf\u7a0b<\/p>\n<pre><code class=\"language-python\">import threading\n\ndef run(n):\n    con.acquire()\n    con.wait()\n    print(&quot;run the thread: %s&quot; %n)\n    con.release()\n\nif __name__ == &#039;__main__&#039;:\n\n    con = threading.Condition()\n    for i in range(10):\n        t = threading.Thread(target=run, args=(i,))\n        t.start()\n\n    while True:\n        inp = input(&#039;&gt;&gt;&gt;&#039;)\n        if inp == &#039;q&#039;:\n            break\n        con.acquire()\n        con.notify(int(inp))\n        con.release()\ndef condition_func():\n\n    ret = False\n    inp = input(&#039;&gt;&gt;&gt;&#039;)\n    if inp == &#039;1&#039;:\n        ret = True\n\n    return ret\n\ndef run(n):\n    con.acquire()\n    con.wait_for(condition_func)\n    print(&quot;run the thread: %s&quot; %n)\n    con.release()\n\nif __name__ == &#039;__main__&#039;:\n\n    con = threading.Condition()\n    for i in range(10):\n        t = threading.Thread(target=run, args=(i,))\n        t.start()<\/code><\/pre>\n<h2>\u5341\u4e09\u3001\u5b9a\u65f6\u5668<\/h2>\n<p><strong><em>*\u5b9a\u65f6\u5668\uff0c\u6307\u5b9an\u79d2\u540e\u6267\u884c\u67d0\u64cd\u4f5c*<\/em><\/strong><\/p>\n<pre><code class=\"language-bash\">from threading import Timer\n\ndef hello():\n    print(&quot;hello, world&quot;)\n\nt = Timer(1, hello)\nt.start()  # after 1 seconds, &quot;hello, world&quot; will be printed<\/code><\/pre>\n<p>\u9a8c\u8bc1\u7801\u5b9a\u65f6\u5668<\/p>\n<pre><code class=\"language-bash\">from threading import Timer\nimport random,time\n\nclass Code:\n    def __init__(self):\n        self.make_cache()\n\n    def make_cache(self,interval=5):\n        self.cache=self.make_code()\n        print(self.cache)\n        self.t=Timer(interval,self.make_cache)\n        self.t.start()\n\n    def make_code(self,n=4):\n        res=&#039;&#039;\n        for i in range(n):\n            s1=str(random.randint(0,9))\n            s2=chr(random.randint(65,90))\n            res+=random.choice([s1,s2])\n        return res\n\n    def check(self):\n        while True:\n            inp=input(&#039;&gt;&gt;: &#039;).strip()\n            if inp.upper() ==  self.cache:\n                print(&#039;\u9a8c\u8bc1\u6210\u529f&#039;,end=&#039;\\n&#039;)\n                self.t.cancel()\n                break\n\nif __name__ == &#039;__main__&#039;:\n    obj=Code()\n    obj.check()<\/code><\/pre>\n<h2>\u5341\u56db\u3001\u7ebf\u7a0bqueue<\/h2>\n<p>queue\u961f\u5217 \uff1a\u4f7f\u7528import queue\uff0c\u7528\u6cd5\u4e0e\u8fdb\u7a0bQueue\u4e00\u6837<\/p>\n<p>queue is especially useful in threaded programming when information must be exchanged safely between multiple threads.<\/p>\n<p>\u2022 <strong><strong>*class***<\/strong> *<\/strong>*<em>queue.&#8220;Queue*<\/em>*<strong><strong><em>*(*maxsize=0\\<\/em>) #\u5148\u8fdb\u5148\u51fa\\<\/strong><\/strong><\/p>\n<pre><code class=\"language-python\">import queue\n\nq=queue.Queue()\nq.put(&#039;first&#039;)\nq.put(&#039;second&#039;)\nq.put(&#039;third&#039;)\n\nprint(q.get())\nprint(q.get())\nprint(q.get())\n&#039;&#039;&#039;\n\u7ed3\u679c(\u5148\u8fdb\u5148\u51fa):\nfirst\nsecond\nthird\n&#039;&#039;&#039;<\/code><\/pre>\n<p><strong><strong>*class***<\/strong> *<\/strong>*<em>queue.&#8220;LifoQueue*<\/em>*<strong><strong><em>*(*maxsize=0*) #last in fisrt out*<\/em><\/strong>#*<\/strong>*\u540e\u8fdb\u5148\u51fa****<\/p>\n<pre><code class=\"language-python\">import queue\n\nq=queue.LifoQueue()\nq.put(&#039;first&#039;)\nq.put(&#039;second&#039;)\nq.put(&#039;third&#039;)\n\nprint(q.get())\nprint(q.get())\nprint(q.get())\n&#039;&#039;&#039;\n\u7ed3\u679c(\u540e\u8fdb\u5148\u51fa):\nthird\nsecond\nfirst\n&#039;&#039;&#039;<\/code><\/pre>\n<p><strong><strong>*class***<\/strong> *<\/strong>*<em>queue.&#8220;PriorityQueue*<\/em>*<strong><strong><em>*(*maxsize=0\\<\/em>) #\u5b58\u50a8\u6570\u636e\u65f6\u53ef\u8bbe\u7f6e\u4f18\u5148\u7ea7\u7684\u961f\u5217\\<\/strong><\/strong><\/p>\n<pre><code class=\"language-python\">import queue\n\nq=queue.PriorityQueue()\n#put\u8fdb\u5165\u4e00\u4e2a\u5143\u7ec4,\u5143\u7ec4\u7684\u7b2c\u4e00\u4e2a\u5143\u7d20\u662f\u4f18\u5148\u7ea7(\u901a\u5e38\u662f\u6570\u5b57,\u4e5f\u53ef\u4ee5\u662f\u975e\u6570\u5b57\u4e4b\u95f4\u7684\u6bd4\u8f83),\u6570\u5b57\u8d8a\u5c0f\u4f18\u5148\u7ea7\u8d8a\u9ad8\nq.put((20,&#039;a&#039;))\nq.put((10,&#039;b&#039;))\nq.put((30,&#039;c&#039;))\n\nprint(q.get())\nprint(q.get())\nprint(q.get())\n&#039;&#039;&#039;\n\u7ed3\u679c(\u6570\u5b57\u8d8a\u5c0f\u4f18\u5148\u7ea7\u8d8a\u9ad8,\u4f18\u5148\u7ea7\u9ad8\u7684\u4f18\u5148\u51fa\u961f):\n(10, &#039;b&#039;)\n(20, &#039;a&#039;)\n(30, &#039;c&#039;)\n&#039;&#039;&#039;<\/code><\/pre>\n<p>\u5176\u4ed6<\/p>\n<pre><code class=\"language-python\">Constructor for a priority queue. maxsize is an integer that sets the upperbound limit on the number of items that can be placed in the queue. Insertion will block once this size has been reached, until queue items are consumed. If maxsize is less than or equal to zero, the queue size is infinite.\n\n\u6784\u9020\u4e00\u4e2a\u4f18\u5148\u7ea7\u961f\u5217,\u5176\u4e2dmaxsize\u662f\u4e00\u4e2a\u6574\u6570,\u7528\u4e8e\u8bbe\u7f6e\u53ef\u4ee5\u653e\u5165\u961f\u5217\u7684\u9879\u76ee\u6570\u91cf\u7684\u4e0a\u9650.\u4e00\u65e6\u8fbe\u5230\u8fd9\u4e2a\u4e0a\u9650\uff0c\u63d2\u5165\u5c31\u4f1a\u963b\u585e\uff0c\u76f4\u5230\u961f\u5217\u4e2d\u6709\u9879\u76ee\u88ab\u6d88\u8017\u3002\u5982\u679cmaxsize\u5c0f\u4e8e\u6216\u7b49\u4e8e0\uff0c\u5219\u961f\u5217\u957f\u5ea6\u4e3a\u65e0\u7a77\u5927\u3002\n\nThe lowest valued entries are retrieved first (the lowest valued entry is the one returned by sorted(list(entries))[0]). A typical pattern for entries is a tuple in the form: (priority_number, data).\n\n\u9996\u5148\u68c0\u7d22\u6700\u4f4e\u503c\u7684\u6761\u76ee(\u6700\u4f4e\u503c\u7684\u6761\u76ee\u662f\u6307\u5217\u8868\u7ecf\u8fc7\u6392\u5e8f\u540e\u53d6\u5230\u7684\u7d22\u5f15\u4e3a0\u7684\u90a3\u4e2a\u5143\u7d20,\u4e00\u822c\u6761\u76ee\u662f(\u4f18\u5148\u7ea7\u6570\u5b57,\u6570\u636e)\u8fd9\u79cd\u5143\u7ec4\u7684\u5f62\u5f0f\n\nexception queue.Empty\nException raised when non-blocking get() (or get_nowait()) is called on a Queue object which is empty.\n\n\u5f53\u8868\u793a\u975e\u963b\u585e\u7684get()\u6216get_nowait()\u5728\u4e00\u4e2a\u7a7a\u7684\u961f\u5217\u5bf9\u8c61\u4e2d\u88ab\u8c03\u7528\u65f6,\u4f1a\u629b\u51fa\u5f02\u5e38\n\nexception queue.Full\nException raised when non-blocking put() (or put_nowait()) is called on a Queue object which is full.\n\n\u5f53\u8868\u793a\u975e\u963b\u585e\u7684put()\u6216put_nowait()\u5728\u4e00\u4e2a\u6ee1\u7684\u961f\u5217\u5bf9\u8c61\u4e2d\u88ab\u8c03\u7528\u65f6,\u4f1a\u629b\u51fa\u5f02\u5e38\n\nQueue.qsize()\nQueue.empty() #return True if empty  \n\n\u5f53\u961f\u5217\u4e3a\u7a7a\u8fd4\u56deTrue\n\nQueue.full() # return True if full \n\n\u5f53\u961f\u5217\u4e3a\u6ee1\u8fd4\u56deTrue\n\nQueue.put(item, block=True, timeout=None)\nPut item into the queue. If optional args block is true and timeout is None (the default), block if necessary until a free slot is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Full exception if no free slot was available within that time. Otherwise (block is false), put an item on the queue if a free slot is immediately available, else raise the Full exception (timeout is ignored in that case).\n\n\u5c06\u4e00\u4e2a\u9879\u653e\u5165\u961f\u5217\u3002\u5982\u679c\u53ef\u9009\u53c2\u6570block\u4e3atrue\u5e76\u4e14timeout\u4e3aNone(\u9ed8\u8ba4\u503c)\uff0c\u5219\u5728\u5fc5\u8981\u65f6\u963b\u585e\uff0c\u76f4\u5230\u6709\u7a7a\u95f2\u69fd\u53ef\u7528\u3002\u5982\u679c\u53c2\u6570timeout\u662f\u4e00\u4e2a\u6b63\u6570\uff0c\u5b83\u6700\u591a\u963b\u585etimeout\u79d2\uff0c\u5982\u679c\u5728\u8fd9\u6bb5\u65f6\u95f4\u5185\u6ca1\u6709\u53ef\u7528\u7684\u7a7a\u95f2\u69fd\uff0c\u5219\u4f1a\u5f15\u53d1Full\u5f02\u5e38\u3002\u5426\u5219(block\u4e3afalse)\uff0c\u5982\u679c\u6709\u7a7a\u95f2\u69fd\u53ef\u7528\uff0c\u5219\u5c06\u4e00\u4e2a\u9879\u76ee\u653e\u5165\u961f\u5217\u4e2d\uff0c\u5426\u5219\u5f15\u53d1Full\u5f02\u5e38(\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0ctimeout\u88ab\u5ffd\u7565)\u3002\n\nQueue.put_nowait(item)\nEquivalent to put(item, False).\n\nQueue.get(block=True, timeout=None)\nRemove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available. If timeout is a positive number, it blocks at most timeout seconds and raises the Empty exception if no item was available within that time. Otherwise (block is false), return an item if one is immediately available, else raise the Empty exception (timeout is ignored in that case).\n\n\u4ece\u961f\u5217\u4e2d\u79fb\u9664\u5e76\u8fd4\u56de\u4e00\u4e2a\u9879\u3002\u5982\u679c\u53ef\u9009\u53c2\u6570block\u4e3atrue\u5e76\u4e14timeout\u4e3aNone(\u9ed8\u8ba4\u503c)\uff0c\u5219\u5728\u5fc5\u8981\u65f6\u963b\u585e\uff0c\u76f4\u5230\u6709\u53ef\u7528\u7684\u9879\u3002\u5982\u679ctimeout\u4e3a\u6b63\u6570\uff0c\u5219\u6700\u591a\u963b\u585etimeout\u79d2\uff0c\u5982\u679c\u5728\u8be5\u65f6\u95f4\u5185\u6ca1\u6709\u53ef\u7528\u9879\uff0c\u5219\u629b\u51faEmpty\u5f02\u5e38\u3002\u5426\u5219(block\u4e3afalse)\uff0c\u5982\u679c\u4e00\u4e2a\u9879\u76ee\u53ef\u7528\uff0c\u5219\u8fd4\u56de\u90a3\u4e2a\u9879\u76ee\uff0c\u5426\u5219\u5f15\u53d1Empty\u5f02\u5e38(\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0ctimeout\u88ab\u5ffd\u7565)\u3002\n\nQueue.get_nowait()\nEquivalent to get(False).\n\nTwo methods are offered to support tracking whether enqueued tasks have been fully processed by daemon consumer threads.\n\n\u63d0\u4f9b\u4e86\u4e24\u79cd\u65b9\u6cd5\u6765\u652f\u6301\u8ffd\u8e2a\u8fdb\u5165\u961f\u5217\u7684\u4efb\u52a1\u662f\u5426\u5df2\u88ab\u751f\u4ea7\u8005\u7684\u5b88\u62a4\u7ebf\u7a0b\u5b8c\u5168\u5904\u7406\u3002\n\nQueue.task_done()\nIndicate that a formerly enqueued task is complete. Used by queue consumer threads. For each get() used to fetch a task, a subsequent call to task_done() tells the queue that the processing on the task is complete.\n\n\u5047\u5b9a\u5148\u524d\u8fdb\u5165\u961f\u5217\u7684\u4efb\u52a1\u5df2\u5b8c\u6210\u3002\u5e76\u4e14\u88ab\u961f\u5217\u751f\u4ea7\u8005\u4f7f\u7528\u3002\u5bf9\u4e8e\u6bcf\u4e2a\u7528\u4e8e\u83b7\u53d6\u4efb\u52a1\u7684get()\uff0c\u540e\u7eed\u5bf9task_done()\u7684\u8c03\u7528\u90fd\u4f1a\u544a\u8bc9\u961f\u5217\u4efb\u52a1\u7684\u5904\u7406\u5df2\u7ecf\u5b8c\u6210\u3002\n\nIf a join() is currently blocking, it will resume when all items have been processed (meaning that a task_done() call was received for every item that had been put() into the queue).\n\n\u5982\u679cjoin()\u5f53\u524d\u6b63\u88ab\u963b\u585e\uff0c\u5b83\u5c06\u5728\u6240\u6709\u9879\u90fd\u88ab\u5904\u7406\u5b8c\u65f6\u6062\u590d(\u8fd9\u610f\u5473\u7740\u5bf9\u4e8e\u6bcf\u4e2a\u5df2\u7ecfput()\u5230\u961f\u5217\u4e2d\u7684\u9879\u90fd\u63a5\u6536\u5230task_done()\u8c03\u7528)\u3002\n\nRaises a ValueError if called more times than there were items placed in the queue.\n\n\u5982\u679c\u8c03\u7528\u6b21\u6570\u8d85\u8fc7\u653e\u5165\u961f\u5217\u7684\u9879\u6570\uff0c\u5c06\u5f15\u53d1ValueError\u3002\n\nQueue.join() \n\n\u963b\u585e,\u76f4\u5230queue\u88ab\u6d88\u8d39\u5b8c\u6bd5<\/code><\/pre>\n<h2>\u5341\u4e94\u3001Python\u6807\u51c6\u6a21\u5757\u2013concurrent.futures<\/h2>\n<p><a href=\"https:\/\/link.zhihu.com\/?target=https%3A\/\/docs.python.org\/dev\/library\/concurrent.futures.html\"><strong><em>*<\/em>https:\/\/docs.python.org\/dev\/library\/concurrent.futures.html*<em>\\<\/em><\/strong><\/a><\/p>\n<pre><code class=\"language-python\">#1 \u4ecb\u7ecd\nconcurrent.futures\u6a21\u5757\u63d0\u4f9b\u4e86\u9ad8\u5ea6\u5c01\u88c5\u7684\u5f02\u6b65\u8c03\u7528\u63a5\u53e3\nThreadPoolExecutor\uff1a\u7ebf\u7a0b\u6c60\uff0c\u63d0\u4f9b\u5f02\u6b65\u8c03\u7528\nProcessPoolExecutor: \u8fdb\u7a0b\u6c60\uff0c\u63d0\u4f9b\u5f02\u6b65\u8c03\u7528\nBoth implement the same interface, which is defined by the abstract Executor class.\n\n#2 \u57fa\u672c\u65b9\u6cd5\n#submit(fn, *args, **kwargs)\n\u5f02\u6b65\u63d0\u4ea4\u4efb\u52a1\n\n#map(func, *iterables, timeout=None, chunksize=1) \n\u53d6\u4ee3for\u5faa\u73afsubmit\u7684\u64cd\u4f5c\n\n#shutdown(wait=True) \n\u76f8\u5f53\u4e8e\u8fdb\u7a0b\u6c60\u7684pool.close()+pool.join()\u64cd\u4f5c\nwait=True\uff0c\u7b49\u5f85\u6c60\u5185\u6240\u6709\u4efb\u52a1\u6267\u884c\u5b8c\u6bd5\u56de\u6536\u5b8c\u8d44\u6e90\u540e\u624d\u7ee7\u7eed\nwait=False\uff0c\u7acb\u5373\u8fd4\u56de\uff0c\u5e76\u4e0d\u4f1a\u7b49\u5f85\u6c60\u5185\u7684\u4efb\u52a1\u6267\u884c\u5b8c\u6bd5\n\u4f46\u4e0d\u7ba1wait\u53c2\u6570\u4e3a\u4f55\u503c\uff0c\u6574\u4e2a\u7a0b\u5e8f\u90fd\u4f1a\u7b49\u5230\u6240\u6709\u4efb\u52a1\u6267\u884c\u5b8c\u6bd5\nsubmit\u548cmap\u5fc5\u987b\u5728shutdown\u4e4b\u524d\n\n#result(timeout=None)\n\u53d6\u5f97\u7ed3\u679c\n\n#add_done_callback(fn)\n\u56de\u8c03\u51fd\u6570<\/code><\/pre>\n<p>ProcessPoolExecutor<\/p>\n<pre><code class=\"language-python\">#\u4ecb\u7ecd\nThe ProcessPoolExecutor class is an Executor subclass that uses a pool of processes to execute calls asynchronously. ProcessPoolExecutor uses the multiprocessing module, which allows it to side-step the Global Interpreter Lock but also means that only picklable objects can be executed and returned.\n\nProcessPoolExecutor\u7c7b\u662fExecutor\u7684\u5b50\u7c7b\uff0c\u5b83\u4f7f\u7528\u4e00\u4e2a\u8fdb\u7a0b\u6c60\u6765\u5f02\u6b65\u6267\u884c\u8c03\u7528\u3002ProcessPoolExecutor\u4f1a\u8c03\u7528\u591a\u8fdb\u7a0b\u6a21\u5757\uff0c\u8fd9\u5141\u8bb8\u5b83\u907f\u5f00\u5168\u5c40\u89e3\u91ca\u5668\u9501\uff0c\u4f46\u4e5f\u610f\u5473\u7740\u53ea\u80fd\u6267\u884c\u548c\u8fd4\u56de\u53efpickle\u7684\u5bf9\u8c61\u3002\n\nclass concurrent.futures.ProcessPoolExecutor(max_workers=None, mp_context=None)\nAn Executor subclass that executes calls asynchronously using a pool of at most max_workers processes. If max_workers is None or not given, it will default to the number of processors on the machine. If max_workers is lower or equal to 0, then a ValueError will be raised.\n\u80fd\u591f\u5f02\u6b65\u8c03\u7528\u6570\u91cf\u4e0d\u8d85\u8fc7\u53c2\u6570max_workers\u7684\u5b50\u8fdb\u7a0b,\u5982\u679cmax_workers\u4e3aNone\u6216\u672a\u7ed9\u51fa\uff0c\u5219\u9ed8\u8ba4\u503c\u4e3a\u673a\u5668\u4e0a\u7684\u5904\u7406\u5668\u6570\u3002\u5982\u679cmax_workers\u5c0f\u4e8e\u6216\u7b49\u4e8e0\uff0c\u5219\u4f1a\u629b\u51fa\u5f02\u5e38ValueError\n\n#\u7528\u6cd5\nfrom concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor\n\nimport os,time,random\ndef task(n):\n    print(&#039;%s is runing&#039; %os.getpid())\n    time.sleep(random.randint(1,3))\n    return n**2\n\nif __name__ == &#039;__main__&#039;:\n\n    executor=ProcessPoolExecutor(max_workers=3)\n\n    futures=[]\n    for i in range(11):\n        future=executor.submit(task,i)\n        futures.append(future)\n    executor.shutdown(True)\n    print(&#039;+++&gt;&#039;)\n    for future in futures:\n        print(future.result())<\/code><\/pre>\n<p>ThreadPoolExecutor<\/p>\n<p>*#\u4ecb\u7ecd<strong><br \/>\n<em>ThreadPoolExecutor <strong>is<\/strong> an Executor subclass that uses a pool of threads to execute calls asynchronously.<\/em><br \/>\n<em>ThreadPoolExecutor\u662fExecutor\u7684\u4e00\u4e2a\u5b50\u7c7b,\u53ef\u4ee5\u5f02\u6b65\u8c03\u7528\u7ebf\u7a0b\u6c60\u91cc\u7684\u7ebf\u7a0b<\/em><br \/>\n<em><strong>class<\/strong> concurrent.futures.ThreadPoolExecutor(max_workers=None, thread_name_prefix=&#8221;)<\/em><br \/>\n<em>An Executor subclass that uses a pool of at most max_workers threads to execute calls asynchronously.<\/em><br \/>\n<em>\u80fd\u591f\u5f02\u6b65\u8c03\u7528\u6570\u91cf\u4e0d\u8d85\u8fc7\u53c2\u6570max_workers\u7684\u5b50\u8fdb\u7a0b.<\/em><br \/>\n<\/strong><br \/>\n<em>Changed <strong>in<\/strong> version 3.5: If max_workers <strong>is<\/strong> None <strong>or<\/strong> <strong>not<\/strong> given, it will default to the number of processors on the machine, multiplied by 5, assuming that ThreadPoolExecutor <strong>is<\/strong> often used to overlap I\/O instead of CPU work <strong>and<\/strong> the number of workers should be higher than the number of workers <strong>for<\/strong> ProcessPoolExecutor.<\/em><br \/>\n<em>3.5\u7248\u672c\u4e2d\u7684\u53d8\u5316:\u5982\u679cmax_workers\u4e3aNone\u6216\u8005\u6ca1\u6709\u88ab\u6307\u5b9a,\u5b83\u5c06\u9ed8\u8ba4\u4e3a\u8ba1\u7b97\u673a\u7684\u5904\u7406\u5668\u4e2a\u6570\u4e58\u4ee55,\u5047\u8bbeThreadPoolExecutor(\u7ebf\u7a0b\u6c60)\u901a\u5e38\u7528\u4e8e\u91cd\u590dI \/ O\u64cd\u4f5c\u800c\u4e0d\u662fCPU\u7684\u8ba1\u7b97,\u90a3\u4e48\u5b83\u7684\u5b9e\u9645\u6548\u7387\u4f1a\u4f4e\u4e8eProcessPoolExecutor(\u8fdb\u7a0b\u6c60)<\/em><br \/>\n<strong><br \/>\n<em>New <strong>in<\/strong> version 3.6: The thread_name_prefix argument was added to allow users to control the threading.Thread names <strong>for<\/strong> worker threads created by the pool <strong>for<\/strong> easier debugging.<\/em><br \/>\n<em>3.6\u7248\u672c\u4e2d\u65b0\u589e\u529f\u80fd:\u6dfb\u52a0\u4e86thread_name_prefix\u53c2\u6570\uff0c\u5141\u8bb8\u7528\u6237\u66f4\u65b9\u4fbf\u5730\u63a7\u5236\u7ebf\u7a0b\u3002\u53ef\u4ee5\u81ea\u5b9a\u4e49\u7531\u7ebf\u7a0b\u6c60\u521b\u5efa\u7684\u7ebf\u7a0b\u540d\uff0c\u4ee5\u4fbf\u4e8e\u8c03\u8bd5\u3002<\/em><br \/>\n<\/strong><br \/>\n<strong>#\u7528\u6cd5<\/strong><br \/>\n*\u4e0eProcessPoolExecutor\u76f8\u540c<\/p>\n<p>map\u7684\u7528\u6cd5<\/p>\n<pre><code class=\"language-python\">from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor\n\nimport os,time,random\ndef task(n):\n    print(&#039;%s is runing&#039; %os.getpid())\n    time.sleep(random.randint(1,3))\n    return n**2\n\nif __name__ == &#039;__main__&#039;:\n\n    executor=ThreadPoolExecutor(max_workers=3)\n\n    # for i in range(11):\n    #     future=executor.submit(task,i)\n\n    executor.map(task,range(1,12)) #map\u53d6\u4ee3\u4e86for+submit\n\u56de\u8c03\u51fd\u6570\nfrom concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor\nfrom multiprocessing import Pool\nimport requests\nimport json\nimport os\n\ndef get_page(url):\n    print(&#039;&lt;\u8fdb\u7a0b%s&gt; get %s&#039; %(os.getpid(),url))\n    respone=requests.get(url)\n    if respone.status_code == 200:\n        return {&#039;url&#039;:url,&#039;text&#039;:respone.text}\n\ndef parse_page(res):\n    res=res.result()\n    print(&#039;&lt;\u8fdb\u7a0b%s&gt; parse %s&#039; %(os.getpid(),res[&#039;url&#039;]))\n    parse_res=&#039;url:&lt;%s&gt; size:[%s]\\n&#039; %(res[&#039;url&#039;],len(res[&#039;text&#039;]))\n    with open(&#039;db.txt&#039;,&#039;a&#039;) as f:\n        f.write(parse_res)\n\nif __name__ == &#039;__main__&#039;:\n    urls=[\n        &#039;https:\/\/www.baidu.com&#039;,\n        &#039;https:\/\/www.python.org&#039;,\n        &#039;https:\/\/www.openstack.org&#039;,\n        &#039;https:\/\/help.github.com\/&#039;,\n        &#039;http:\/\/www.sina.com.cn\/&#039;\n    ]\n\n    # p=Pool(3)\n    # for url in urls:\n    #     p.apply_async(get_page,args=(url,),callback=pasrse_page)\n    # p.close()\n    # p.join()\n\n    p=ProcessPoolExecutor(3)\n    for url in urls:\n        p.submit(get_page,url).add_done_callback(parse_page) #parse_page\u62ff\u5230\u7684\u662f\u4e00\u4e2afuture\u5bf9\u8c61obj\uff0c\u9700\u8981\u7528obj.result()\u62ff\u5230\u7ed3\u679c<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u591a\u7ebf\u7a0b\uff08\u5b9e\u64cd\uff09 \u4e00\u3001threading\u6a21\u5757\u4ecb\u7ecd multiprocess\u6a21\u5757\u7684\u5b8c\u5168\u6a21\u4eff\u4e86threading\u6a21\u5757 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":6031,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,281,370],"tags":[],"_links":{"self":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts\/4881"}],"collection":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4881"}],"version-history":[{"count":0,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/posts\/4881\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=\/wp\/v2\/media\/6031"}],"wp:attachment":[{"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/egonlin.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}