1. <i id='n3dJh'><tr id='n3dJh'><dt id='n3dJh'><q id='n3dJh'><span id='n3dJh'><b id='n3dJh'><form id='n3dJh'><ins id='n3dJh'></ins><ul id='n3dJh'></ul><sub id='n3dJh'></sub></form><legend id='n3dJh'></legend><bdo id='n3dJh'><pre id='n3dJh'><center id='n3dJh'></center></pre></bdo></b><th id='n3dJh'></th></span></q></dt></tr></i><div id='n3dJh'><tfoot id='n3dJh'></tfoot><dl id='n3dJh'><fieldset id='n3dJh'></fieldset></dl></div>
      1. <tfoot id='n3dJh'></tfoot>
        <legend id='n3dJh'><style id='n3dJh'><dir id='n3dJh'><q id='n3dJh'></q></dir></style></legend>

        <small id='n3dJh'></small><noframes id='n3dJh'>

          <bdo id='n3dJh'></bdo><ul id='n3dJh'></ul>

        浅谈Python中的全局锁(GIL)问题

        时间:2023-12-15
          1. <small id='MX10B'></small><noframes id='MX10B'>

            • <bdo id='MX10B'></bdo><ul id='MX10B'></ul>

              1. <legend id='MX10B'><style id='MX10B'><dir id='MX10B'><q id='MX10B'></q></dir></style></legend>

                <i id='MX10B'><tr id='MX10B'><dt id='MX10B'><q id='MX10B'><span id='MX10B'><b id='MX10B'><form id='MX10B'><ins id='MX10B'></ins><ul id='MX10B'></ul><sub id='MX10B'></sub></form><legend id='MX10B'></legend><bdo id='MX10B'><pre id='MX10B'><center id='MX10B'></center></pre></bdo></b><th id='MX10B'></th></span></q></dt></tr></i><div id='MX10B'><tfoot id='MX10B'></tfoot><dl id='MX10B'><fieldset id='MX10B'></fieldset></dl></div>
                  <tbody id='MX10B'></tbody>
                • <tfoot id='MX10B'></tfoot>
                • 浅谈Python中的全局锁(GIL)问题

                  什么是GIL

                  GIL 全称 Global Interpreter Lock,意为全局解释器锁。在 Python 中,一次只能执行一个线程,所以为了保证线程安全,引入了 GIL 的概念。GIL 是 Python 解释器中自带的机制,用来保证同一时刻只有一个线程在执行 Python 代码。当一个线程开始执行 Python 代码时,GIL 就会获得并锁住 Python 解释器,保证只有这个线程可以接触到解释器。

                  GIL的问题

                  GIL 的存在使得 Python 的多线程执行遭遇瓶颈。虽然 Python 可以使用多进程的方式解决多线程所面临的瓶颈,但多进程的开销相比于多线程会比较大。而且在某些场景下,使用多线程更为方便。

                  举个例子

                  例子1

                  import threading
                  
                  num = 0
                  
                  def thread_test():
                      global num
                      for i in range(1000000):
                          num += 1
                      print(num)
                  
                  thread1 = threading.Thread(target=thread_test)
                  thread2 = threading.Thread(target=thread_test)
                  thread1.start()
                  thread2.start()
                  

                  以上代码会创建两个线程,每个线程都会对 num 进行 1000000 次加 1 操作,并打印最终的计数结果。

                  但是执行的结果可能出乎想象:

                  1265211
                  1394415
                  

                  实际上,我们想要的结果应该是 2000000。原因就在于 GIL。

                  在使用多线程执行 Python 代码时,由于 GIL 的存在,每一个时刻只有一个线程在执行 Python 代码。在本例中,两个线程交替获得 GIL,一次只能做一次加法。最终的结果可能超出预期。

                  例子2

                  import threading
                  
                  num = 0
                  
                  def thread_test():
                      global num
                      for i in range(1000000):
                          num += 1
                      print(num)
                  
                  thread1 = threading.Thread(target=thread_test)
                  thread2 = threading.Thread(target=thread_test)
                  thread3 = threading.Thread(target=thread_test)
                  thread1.start()
                  thread2.start()
                  thread3.start()
                  

                  以上代码会创建三个线程,每个线程都会对 num 进行 1000000 次加 1 操作,并打印最终的计数结果。

                  执行的结果可能如下:

                  2324507
                  2424009
                  3553736
                  

                  同样也是超出预期的。

                  在这个例子中,如果想要结果正确,可以使用 threading.Lock() 对共享变量进行锁定:

                  import threading
                  
                  num = 0
                  lock = threading.Lock()
                  
                  def thread_test():
                      global num
                      for i in range(1000000):
                          lock.acquire()
                          num += 1
                          lock.release()
                      print(num)
                  
                  thread1 = threading.Thread(target=thread_test)
                  thread2 = threading.Thread(target=thread_test)
                  thread3 = threading.Thread(target=thread_test)
                  thread1.start()
                  thread2.start()
                  thread3.start()
                  

                  使用 lock 后,每个线程在执行对 num 的加 1 操作前都会尝试获取锁,如果拿到锁后才执行加法操作。这样可以保证在同一时刻只有一个线程对 num 进行操作,最终达到正确的结果。

                  上一篇:python调用有道智云API实现文件批量翻译 下一篇:python 线程的暂停, 恢复, 退出详解及实例

                  相关文章

                  <legend id='WjIVT'><style id='WjIVT'><dir id='WjIVT'><q id='WjIVT'></q></dir></style></legend>
                • <tfoot id='WjIVT'></tfoot>

                    <small id='WjIVT'></small><noframes id='WjIVT'>

                    <i id='WjIVT'><tr id='WjIVT'><dt id='WjIVT'><q id='WjIVT'><span id='WjIVT'><b id='WjIVT'><form id='WjIVT'><ins id='WjIVT'></ins><ul id='WjIVT'></ul><sub id='WjIVT'></sub></form><legend id='WjIVT'></legend><bdo id='WjIVT'><pre id='WjIVT'><center id='WjIVT'></center></pre></bdo></b><th id='WjIVT'></th></span></q></dt></tr></i><div id='WjIVT'><tfoot id='WjIVT'></tfoot><dl id='WjIVT'><fieldset id='WjIVT'></fieldset></dl></div>

                    • <bdo id='WjIVT'></bdo><ul id='WjIVT'></ul>