脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Python - Python并发编程:多线程技术详解

Python并发编程:多线程技术详解

2023-10-19 11:05写代码那些事 Python

在这个教程中,我们将带你了解Python多线程!作为一名Python开发者,你可能一直在想如何提高程序性能,让任务同时高效地执行。别担心,本教程将深入浅出地介绍多线程的艺术和威力。一起开始这个令人兴奋的学习之旅吧!

什么是并发编程?

Python并发编程:多线程技术详解

并发编程是指在计算机程序中同时处理多个任务或操作的编程方式。通常情况下,现代计算机系统都具有多核处理器或支持同时执行多个线程的能力,因此并发编程可以充分利用这些硬件资源,提高程序的执行效率和性能。

在并发编程中,任务被划分为多个子任务,并通过同时执行这些子任务来实现并发性。这些子任务可以是线程、进程、协程或其他并发机制的实例。

并发编程可以在多个任务之间实现高效的任务切换,使得看似同时执行的任务在时间上交替进行,从而让用户感觉到任务在同时进行。

并发编程通常用于以下情况:

  1. 提高程序性能:在多核处理器上,通过并发执行多个任务,可以充分利用多核资源,提高程序的执行速度和性能。
  2. 增强用户体验:在图形界面或网络应用中,通过并发编程可以让程序在后台同时处理多个任务,提高用户体验和响应速度。
  3. 并行处理:在科学计算、数据处理等领域,通过并发编程可以将复杂任务划分为多个子任务,同时进行处理,从而缩短处理时间。
  4. 实现异步操作:在网络编程、I/O操作等场景中,通过并发编程可以实现异步操作,提高系统的并发能力和吞吐量。

然而,并发编程也面临一些挑战,主要包括:

  1. 竞态条件:多个任务同时访问共享资源时可能会导致数据不一致或错误的结果。
  2. 死锁:多个任务之间因为资源竞争而相互等待,导致程序无法继续执行。
  3. 同步和通信:需要精确控制任务之间的同步和通信,确保数据正确传递和共享。

为了解决这些挑战,编程中需要使用适当的同步机制,如锁、条件变量、信号量等,来保证多个任务之间的安全协作。并发编程需要仔细设计和管理,以确保程序的正确性和性能。

线程安全是并发编程的基础

线程安全是指多线程环境下对共享资源的访问和操作是安全的,不会导致数据不一致或产生竞态条件。由于Python的全局解释器锁(Global Interpreter Lock,GIL),在同一时刻只允许一个线程执行Python字节码,所以对于CPU密集型任务,多线程并不能真正实现并行执行。然而,对于I/O密集型任务,多线程可以在某种程度上提高程序的性能。

下面是一些Python中处理线程安全的方法:

  1. 使用锁(Lock): 锁是一种最常见的线程同步机制。通过使用threading.Lock对象,可以确保在同一时刻只有一个线程可以访问共享资源。在访问共享资源前,线程需要先获取锁,完成操作后再释放锁。
  2. 使用条件变量(Condition): 条件变量提供了一种更复杂的线程同步机制,它可以让一个或多个线程等待特定条件的发生后再继续执行。threading.Condition对象通常与锁一起使用。
  3. 使用信号量(Semaphore): 信号量用于控制同时访问某个共享资源的线程数量。通过threading.Semaphore对象,可以指定允许同时访问共享资源的线程数量,超过数量的线程将被阻塞。
  4. 使用互斥量(Mutex): 互斥量是一种特殊的锁,它只能被锁住的线程解锁,其他线程无法解锁。在Python中,可以使用threading.RLock(可重入锁,即递归锁)来实现互斥量的功能。
  5. 使用线程安全的数据结构: Python提供了一些线程安全的数据结构,如queue.Queue(队列)、collections.deque(双端队列)等,它们内部实现了线程同步机制,可以直接在多线程环境中使用,避免手动处理锁的逻辑。

需要注意的是,虽然上述方法可以帮助处理线程安全,但并不能完全消除线程竞态条件的发生。正确处理线程安全需要谨慎编写代码逻辑,合理使用线程同步机制,并对共享资源的访问进行严格控制。

以下是一些简单的Python多线程例子,演示了如何使用锁和条件变量来保证线程安全:

使用锁实现线程安全的计数器

  1. import threading 
  2.  
  3. class Counter: 
  4.     def __init__(self): 
  5.         self.value = 0 
  6.         self.lock = threading.Lock() 
  7.  
  8.     def increment(self): 
  9.         with self.lock: 
  10.             self.value += 1 
  11.  
  12.     def decrement(self): 
  13.         with self.lock: 
  14.             self.value -= 1 
  15.  
  16.     def get_value(self): 
  17.         with self.lock: 
  18.             return self.value 
  19.  
  20. def worker(counter, num): 
  21.     for _ in range(num): 
  22.         counter.increment() 
  23.  
  24. counter = Counter() 
  25. threads = [] 
  26. num_threads = 5 
  27. num_iterations = 100000 
  28.  
  29. for _ in range(num_threads): 
  30.     thread = threading.Thread(target=worker, args=(counter, num_iterations)) 
  31.     threads.append(thread) 
  32.     thread.start() 
  33.  
  34. for thread in threads: 
  35.     thread.join() 
  36.  
  37. print("Final counter value:", counter.get_value()) # 应该输出:Final counter value: 500000 

使用条件变量实现生产者-消费者模式:

  1. import threading 
  2. import time 
  3. import random 
  4.  
  5. class Buffer: 
  6.     def __init__(self, capacity): 
  7.         self.capacity = capacity 
  8.         self.buffer = [] 
  9.         self.lock = threading.Lock() 
  10.         self.not_empty = threading.Condition(self.lock) 
  11.         self.not_full = threading.Condition(self.lock) 
  12.  
  13.     def produce(self, item): 
  14.         with self.not_full: 
  15.             while len(self.buffer) >= self.capacity: 
  16.                 self.not_full.wait() 
  17.             self.buffer.append(item) 
  18.             print(f"Produced: {item}"
  19.             self.not_empty.notify() 
  20.  
  21.     def consume(self): 
  22.         with self.not_empty: 
  23.             while len(self.buffer) == 0: 
  24.                 self.not_empty.wait() 
  25.             item = self.buffer.pop(0) 
  26.             print(f"Consumed: {item}"
  27.             self.not_full.notify() 
  28.  
  29. def producer(buffer): 
  30.     for i in range(1, 6): 
  31.         item = f"Item-{i}" 
  32.         buffer.produce(item) 
  33.         time.sleep(random.random()) 
  34.  
  35. def consumer(buffer): 
  36.     for _ in range(5): 
  37.         buffer.consume() 
  38.         time.sleep(random.random()) 
  39.  
  40. buffer = Buffer(capacity=3) 
  41.  
  42. producer_thread = threading.Thread(target=producer, args=(buffer,)) 
  43. consumer_thread = threading.Thread(target=consumer, args=(buffer,)) 
  44.  
  45. producer_thread.start() 
  46. consumer_thread.start() 
  47.  
  48. producer_thread.join() 
  49. consumer_thread.join() 

原文地址:https://www.toutiao.com/article/7273366935008543288/

延伸 · 阅读

精彩推荐
  • PythonFlask接收上传图片方法实现

    Flask接收上传图片方法实现

    本文主要介绍了Flask接收上传图片方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着...

    别把代码当饭吃9852022-07-07
  • Pythonpython beautifulsoup4 模块详情

    python beautifulsoup4 模块详情

    本文主要介绍了python beautifulsoup4模块详情,BeautifulSoup4是一款python解析库,主要用于解析HTML和XML,在爬虫知识体系中解析 HTML 会比较多一些,下文更多相关内容...

    梦想橡皮擦8172023-02-06
  • Pythontensorflow 加载部分变量的实例讲解

    tensorflow 加载部分变量的实例讲解

    今天小编就为大家分享一篇tensorflow 加载部分变量的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    imperfect0011232021-03-23
  • Pythonpython实战教程之OCR文字识别方法汇总

    python实战教程之OCR文字识别方法汇总

    ocr是一种光学字符识别技术,简单来说它能够识别出图像中的文字并且将其给取出来,下面这篇文章主要给大家介绍了关于python实战教程之OCR文字识别方法的...

    wu_zhiyuan6052023-05-05
  • Pythonpython实现的简单窗口倒计时界面实例

    python实现的简单窗口倒计时界面实例

    这篇文章主要介绍了python实现的简单窗口倒计时界面,实例分析了Python基于Tkinter操作windows窗口界面的相关技巧,非常具有实用价值,需要的朋友可以参考下...

    work2414372020-06-22
  • Python解决安装pycharm后不能执行python脚本的问题

    解决安装pycharm后不能执行python脚本的问题

    今天小编就为大家分享一篇解决安装pycharm后不能执行python脚本的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    To Change the Fate4032021-05-18
  • Pythonpython中如何正确使用正则表达式的详细模式(Verbose mode expression)

    python中如何正确使用正则表达式的详细模式(Verbose mode expressi

    许多程序设计语言都支持利用正则表达式进行字符串操作,python自然也不例外,下面这篇文章主要给大家介绍了关于在python中如何正确使用正则表达式的详...

    caimouse4312020-12-16
  • Python关于Python3爬虫利器Appium的安装步骤

    关于Python3爬虫利器Appium的安装步骤

    在本篇文章里小编给大家整理的是一篇关于Python3爬虫利器Appium的安装步骤,需要的朋友们可以跟着参考下。 ...

    爱喝马黛茶的安东尼2682020-07-30