• <legend id='cYn34'><style id='cYn34'><dir id='cYn34'><q id='cYn34'></q></dir></style></legend>

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

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

        <tfoot id='cYn34'></tfoot>
        • <bdo id='cYn34'></bdo><ul id='cYn34'></ul>

        Python多线程thread及模块使用实例

        时间:2023-12-17
        • <bdo id='Wgkqv'></bdo><ul id='Wgkqv'></ul>
              <i id='Wgkqv'><tr id='Wgkqv'><dt id='Wgkqv'><q id='Wgkqv'><span id='Wgkqv'><b id='Wgkqv'><form id='Wgkqv'><ins id='Wgkqv'></ins><ul id='Wgkqv'></ul><sub id='Wgkqv'></sub></form><legend id='Wgkqv'></legend><bdo id='Wgkqv'><pre id='Wgkqv'><center id='Wgkqv'></center></pre></bdo></b><th id='Wgkqv'></th></span></q></dt></tr></i><div id='Wgkqv'><tfoot id='Wgkqv'></tfoot><dl id='Wgkqv'><fieldset id='Wgkqv'></fieldset></dl></div>
            • <small id='Wgkqv'></small><noframes id='Wgkqv'>

                <tfoot id='Wgkqv'></tfoot>

                  <tbody id='Wgkqv'></tbody>
                  <legend id='Wgkqv'><style id='Wgkqv'><dir id='Wgkqv'><q id='Wgkqv'></q></dir></style></legend>

                  下面就给您详细讲解“Python多线程thread及模块使用实例”相关知识。

                  1. Python多线程thread的介绍

                  Python提供了多线程的支持,它是通过thread模块实现的。由于GIL(全局解释器锁)的问题,Python的多线程无法实现真正的并发,但是在IO密集型的任务中,多线程还是有着很大的优势的。下面我们来看一下Python多线程的一些基本用法。

                  2. Python多线程thread模块的使用

                  首先,我们需要导入threading模块。Thread()是threading的一个类,我们可以通过实例化这个类来创建线程。

                  2.1 创建线程

                  线程的创建通过调用Thread()类实现,下面是一个简单的例子:

                  import threading
                  
                  def print_hello():
                      print('Hello World!')
                  
                  t = threading.Thread(target=print_hello)
                  t.start()
                  

                  在这个例子中,我们定义了一个函数print_hello(),然后创建了一个线程t,并将这个函数作为参数传给它。最后调用了线程的start()方法,线程就开始执行了。

                  2.2 线程同步

                  线程同步指的是让线程按照一定的顺序执行,避免出现竞争条件的情况。在Python中,可以使用锁来实现线程同步,这里介绍一下常用的Lock类。

                  import threading
                  
                  # 创建一个锁对象
                  lock = threading.Lock()
                  
                  # 全局变量
                  sum = 0
                  
                  def add(n):
                      global sum
                      for i in range(n):
                          # 获取锁
                          lock.acquire()
                          sum += 1
                          # 释放锁
                          lock.release()
                  
                  # 创建两个线程
                  t1 = threading.Thread(target=add, args=(100000,))
                  t2 = threading.Thread(target=add, args=(100000,))
                  
                  # 启动线程
                  t1.start()
                  t2.start()
                  # 等待线程结束
                  t1.join()
                  t2.join()
                  
                  print(sum)
                  

                  在这个例子中,我们创建了一个锁lock,然后定义了一个函数add(n),该函数会让全局变量sum加上n次。在每一次加操作之前,我们都先获取锁,然后执行加操作,在结束后释放锁。接下来,我们创建了两个线程,让它们执行这个函数,最后得到的结果是200000

                  2.3 线程间通信

                  线程间通信指的是线程之间的数据传递或传递消息。在Python中,我们可以使用Queue类来实现线程间通信。下面是一个简单的例子:

                  import threading
                  import queue
                  
                  # 创建一个空的队列
                  q = queue.Queue()
                  
                  # 生产者函数
                  def producer():
                      for i in range(10):
                          # 向队列中添加元素
                          q.put(i)
                          print('produce:', i)
                  
                  # 消费者函数
                  def consumer():
                      while True:
                          # 从队列中获取元素,如果队列为空,则阻塞等待
                          item = q.get()
                          if item is None:
                              break
                          print('consume:', item)
                          # 告诉队列这个元素已经处理完毕
                          q.task_done()
                  
                  # 创建生产者和消费者线程
                  t1 = threading.Thread(target=producer)
                  t2 = threading.Thread(target=consumer)
                  
                  # 启动生产者和消费者线程
                  t1.start()
                  t2.start()
                  
                  # 等待生产者线程结束
                  t1.join()
                  
                  # 阻塞并等待队列中所有元素都被处理完毕
                  q.join()
                  
                  # 给消费者线程发送一个结束信号
                  q.put(None)
                  
                  # 等待消费者线程结束
                  t2.join()
                  

                  在这个例子中,我们创建了一个队列q,然后定义了一个生产者函数producer()和一个消费者函数consumer()。生产者函数会向队列中添加元素,消费者函数会从队列中获取元素并进行处理。

                  接下来我们创建了生产者和消费者两个线程,并启动它们。生产者线程完成任务后退出,消费者线程会阻塞等待从队列中获取元素,直到生产者线程发送一个结束信号。

                  3. Python线程池介绍

                  Python线程池使用ThreadPoolExecutor类来实现。线程池可以让我们不需要每次创建新线程来执行任务,而是预先创建一定数量的线程。任务提交后就会立即执行,当线程池中的线程都处于忙碌状态时,新的任务会被暂时存储在队列中,等待线程的空闲。

                  3.1 创建线程池

                  from concurrent.futures import ThreadPoolExecutor
                  
                  # 创建一个包含10个线程的线程池
                  with ThreadPoolExecutor(max_workers=10) as executor:
                      # 提交任务给线程池处理
                      executor.submit(my_func, *args)
                  

                  在这个例子中,我们使用了Python的上下文管理器(With语句)来自动地管理线程池的创建和销毁。创建线程池的代码只需要一行。使用线程池时,我们只需要不断地向线程池提交需要处理的任务即可。

                  3.2 示例说明:使用Python线程池下载多个图片

                  import os
                  import urllib.request
                  from concurrent.futures import ThreadPoolExecutor
                  
                  # 图片url
                  url_list = ['http://www.gstatic.com/webp/gallery/1.jpg', 'http://www.gstatic.com/webp/gallery/2.jpg', 'http://www.gstatic.com/webp/gallery/3.jpg', 'http://www.gstatic.com/webp/gallery/4.jpg', 'http://www.gstatic.com/webp/gallery/5.jpg']
                  
                  def download_file(url):
                      # 获取文件名
                      filename = os.path.basename(url)
                      # 下载图片
                      urllib.request.urlretrieve(url, filename)
                      print('下载图片成功:', url)
                  
                  # 创建包含3个线程的线程池
                  with ThreadPoolExecutor(max_workers=3) as executor:
                      # 提交任务给线程池下载图片
                      for url in url_list:
                          executor.submit(download_file, url)
                  

                  在这个例子中,我们定义了一个下载文件的函数download_file(),该函数会把图片下载到本地。接下来我们把五张图片的url放在一个列表中,然后通过线程池对每一个url进行下载。我们创建了一个包含3个线程的线程池,线程池会自动地为每一个任务分配一个线程,当所有任务都完成后,线程池会自动停止。

                  4. 总结

                  Python的多线程thread模块和线程池ThreadPoolExecutor类是非常实用的工具,在处理一些需要IO操作的任务时可以大大提高程序运行的效率。但是由于GIL的存在,Python的多线程无法实现真正的并发,所以在处理计算密集型的任务时,不如使用多进程。

                  上一篇:Python数据获取实现图片数据提取 下一篇:Python如何使用opencv进行手势识别详解

                  相关文章

                  <legend id='MMGDH'><style id='MMGDH'><dir id='MMGDH'><q id='MMGDH'></q></dir></style></legend>

                • <small id='MMGDH'></small><noframes id='MMGDH'>

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