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)问题

        GIL 全称 Global Interpreter Lock,意为全局解释器锁。在 Python 中,一次只能执行一个线程,所以为了保证线程安全,引入了 GIL 的概念。GIL 是 Python 解释器中自带的机制,用来保证同一时刻只有一个线程在执行 Python 代码。当一个线程开始执行 Python
          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中有三个内置函数eval()、exec()和compile()来执行动态代码。这些函数能够从字符串参数中读取Python代码并在运行时执行该代码。但是,使用这些函数时必须小心,因为它们的不当使用可能会导致安全漏洞。
                  在Python中,下载网络文本数据到本地内存是常见的操作之一。本文将介绍四种常见的下载网络文本数据到本地内存的实现方法,并提供示例说明。
                  来给你详细讲解下Python 二进制字节流数据的读取操作(bytes与bitstring)。
                  Python 3.x 是 Python 2.x 的下一个重大版本,其中有一些值得注意的区别。 Python 3.0中包含了许多不兼容的变化,这意味着在迁移到3.0之前,必须进行代码更改和测试。本文将介绍主要的差异,并给出一些实例来说明不同点。
                  要在终端里显示图片,需要使用一些Python库。其中一种流行的库是Pillow,它有一个子库PIL.Image可以加载和处理图像文件。要在终端中显示图像,可以使用如下的步骤:
                  在Python中,我们可以使用Pillow库来进行图像处理。具体实现两幅图像合成一幅图像的方法如下:
                  <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>

                              <tbody id='WjIVT'></tbody>