调度程序内的多任务使用多进程,调度一个进程内的多任务使用多线程
函数式创建线程的方式threading模块
在Python中,创建线程主要依赖于threading模块。
使用threading模块中的Thread类,你可以很容易地基于函数模式创建线程。基本步骤包括:
导入threading模块。
定义一个目标函数,这个函数将是线程执行的任务。
创建一个Thread对象,将目标函数作为参数传递给它。
调用Thread对象的start()方法来启动线程。
import threading
import time
# 定义一个简单的函数,这个函数将被线程执行
def print_numbers():
for i in range(5):
time.sleep(1) # 模拟耗时操作
print(i)
# 创建Thread对象,将print_numbers作为目标函数
thread1 = threading.Thread(target=print_numbers)
# 启动线程
thread1.start()
# 主线程继续执行
print("主线程继续执行")
# 注意:如果主线程太快结束,可能不会看到子线程的输出。
# 在实际应用中,你可能需要确保主线程等待子线程完成。
# 例如,使用thread1.join()可以阻塞主线程直到thread1完成。
# thread1.join() # 如果需要等待线程完成,可以取消注释这行
多线程之间是并发执行的,执行顺序随机看cpu调度顺序
继承式创建线程的方式
进程之间的数据不能共享,线程之间的数据可以共享,进程之间数据如果需要共享需要用到队列
多个线程在操作global全局数据时候存在不安全问题,因为线程的执行是并行的,操作的数据又是共享的,有可能同时操作到同一个数据
在Python中,多线程编程时经常需要处理共享资源的问题,以避免数据竞争(race condition)和状态不一致等不安全的情况。为了安全地管理这些共享资源,可以使用threading模块中的Lock锁。
import threading
# 共享计数器
counter = 0
# 创建一个Lock对象
lock = threading.Lock()
def increment_counter():
global counter
for _ in range(100000):
# 在访问共享资源前加锁
lock.acquire()
try:
counter += 1
finally:
# 确保锁最终会被释放
lock.release()
# 创建多个线程
threads = []
for _ in range(10):
t = threading.Thread(target=increment_counter)
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join()
# 使用Lock后,最终结果应该是1000000
print(f"Final counter: {counter}")
我们在 修改counter之前加上了锁(lock.acquire()),并在修改完成后释放锁(lock.release())。这样可以确保在任何给定时间,只有一个线程可以修改counter,从而避免了数据竞争,确保了程序的正确性。
使用try…finally语句块是为了确保即使在发生异常的情况下,锁也能被正确释放,防止死锁的发生。
生产者消费者模式
前边一则写过代码