2 进程,线程和协程 。代码如何实现?你在哪里用过 ?
2.1 进程
2.2 线程
2.3 协程
2.4 进程,线程和协程的使用场景
**GIL 锁(全局解释器锁):** GIL 锁是为了解决 CPython 解释器中多线程并发执行时的问题。
GIL 锁保证了在解释器中,同一时刻只有一个线程在执行 Python 字节码,从而防止了一些线程安全的问题。
但是,GIL 锁并不能解决所有的并发问题,特别是在多核 CPU 上无法发挥多线程的优势。
**互斥锁:** 互斥锁(Mutex)是一种在多线程编程中常用的同步机制,它可以用于保护对共享资源的访问,
防止多个线程同时修改某个共享数据导致的问题。即使有了 GIL 锁,但在一些需要明确控制访问顺序的情况
下,互斥锁仍然是必要的。
总体来说,GIL 锁主要是为了解决 CPython 中的线程安全问题,而互斥锁则是在多线程环境下保护
共享资源的通用手段。
**概念:** 进程是操作系统中执行的一个程序的实例。
每个进程都有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据。
**实现:** 在Python中,可以使用`multiprocessing`模块创建和管理进程。
import multiprocessing
import os
def worker():
print(f"Worker PID: {os.getpid()}")
if __name__ == "__main__":
# 创建进程
process = multiprocessing.Process(target=worker)
# 启动进程
process.start()
# 等待进程结束
process.join()
print("Main process PID:", os.getpid())
**概念:** 线程是进程中的一个执行流,一个进程可以由多个线程同时执行。
**实现:** 在Python中,可以使用`threading`模块创建和管理线程。
import threading
def worker():
print("Worker Thread")
if __name__ == "__main__":
# 创建线程
thread = threading.Thread(target=worker)
# 启动线程
thread.start()
# 等待线程结束
thread.join()
print("Main Thread")
**概念:** 协程是一种用户态的轻量级线程,协程的调度完全由用户控制。
**实现:** 在Python中,可以使用`asyncio`库创建和管理协程。
import asyncio
async def worker():
print("Worker Coroutine")
if __name__ == "__main__":
# 创建事件循环
loop = asyncio.get_event_loop()
# 创建协程任务
task = loop.create_task(worker())
# 运行事件循环
loop.run_until_complete(task)
print("Main Coroutine")
**进程:** 适用于多核CPU,可以充分利用多核优势。每个进程有自己独立的内存空间,相对隔离。
**线程:** 适用于I/O密集型任务,例如网络请求、文件操作等。线程共享同一进程的内存空间,
但需要注意线程安全。
**协程:** 适用于高并发、高IO的场景。协程由用户控制,避免了线程切换的开销,提高了并发性能。
在实际项目中,可能会同时使用这三种技术,根据任务的不同特点选择合适的并发模型。例如,可以使用进程池
处理CPU密集型任务,使用线程池处理I/O密集型任务,使用协程处理高并发、高IO的任务。
**定义:** 鸭子类型是一种动态类型的风格。在鸭子类型中,一个对象的特征不是由继承自特定的类或
实现特定的接口,而是由它所包含的方法和属性决定的。
**思想:** "如果它走起来像鸭子,叫起来也像鸭子,那么它就是鸭子。" 这表示在鸭子类型中,
我们关注的不是对象的类型本身,而是对象的行为。
**实例:** Python 是一种支持鸭子类型的语言。例如,一个函数可能接收一个具有 `len()` 方法的对象,
而不关心对象的具体类型是什么,只要它有合适的方法。
**优势:** 鸭子类型使得代码更加灵活,不需要依赖于特定的继承关系,而是关注对象的能力。
这样可以更好地实现代码的复用和扩展。
class Duck:
def shut(self):
return "嘎嘎!嘎嘎!"
def fly(self):
return "用翅膀飞"
class Person:
def shut(self):
return "我能像鸭子一样嘎嘎叫。"
def fly(self):
return "我用我的手臂飞翔。"
def introduce(entity): # entity实例
print(entity.shut())
print(entity.fly())
# 使用鸭子类型
duck = Duck()
person = Person()
introduce(duck)
introduce(person)
在这个例子中,`Duck` 类和 `Person` 类都没有继承相同的基类,但它们都有 `quack` 和 `fly` 方法。
函数 `introduce` 接受任何具有这两个方法的对象,无论其具体类型是什么。这就是鸭子类型的概念。