
target: 传入 函数开辟线程这个线程要执行的任务线程import threading import time# 方法1直接使用 Thread 类defworker(name,delay):print(f线程 {name} 开始工作)time.sleep(delay)print(f线程 {name} 完成工作)# 创建线程t1threading.Thread(targetworker,args(Thread-1,2))t2threading.Thread(targetworker,args(Thread-2,1))# 启动线程t1.start()t2.start()# 等待线程完成t1.join()t2.join()print(所有线程完成)### 线程同步 互斥锁importthreadingcounter0lockthreading.Lock()defincrement():globalcounterfor_inrange(100000):lock.acquire()# 获取锁 counter1lock.release()# 释放锁# 或者使用 with 语句推荐# with lock:# counter 1# 创建多个线程threads[]for_inrange(5):tthreading.Thread(targetincrement)threads.append(t)t.start()fortinthreads:t.join()print(f最终计数: {counter})#500000## RLock可重入锁# 可重入锁Reentrant Lock 允许同一个线程多次获取同一个锁而不会造成死锁。它会记录锁的持有线程和获取次数。importthreadingrlockthreading.RLock()defrecursive_function(n):withrlock:ifn0:print(f递归深度: {n})recursive_function(n-1)# 同一个线程可以多次获取RLocktthreading.Thread(targetrecursive_function,args(5,))t.start()t.join()## Semaphore信号量import threading import time# 限制同时最多3个线程访问semaphorethreading.Semaphore(3)deflimited_access(name):withsemaphore:print(f{name} 获取访问权限)time.sleep(2)# 模拟工作print(f{name} 释放访问权限)# 创建10个线程threads[]foriinrange(10):tthreading.Thread(targetlimited_access,args(fThread-{i},))threads.append(t)t.start()fortinthreads:t.join()》》》普通的lock 和 Rlockimport threading# 普通 Lock - 同一个线程不能重复获取lockthreading.Lock()deflock_example():lock.acquire()print(第一次获取锁)# lock.acquire() # 死锁线程会永远等待自己lock.release()# RLock - 同一个线程可以重复获取rlockthreading.RLock()defrlock_example():rlock.acquire()print(第一次获取锁)rlock.acquire()# 可以再次获取print(第二次获取锁)rlock.release()# 需要释放相同次数 rlock.release()主线程和子线程 线程守护默认情况下子线程不会随这主线程执行完毕而结束所有主线程会等待所有子线程执行结束才结束。如主线程结束子线程无论是否执行完都是退出程序创建线程时指定daemonTrue或者sub_thread.darmonTruesub_thread.setDaemon(True)线程直接执行是无序的是有CPU决定的进程创建步骤python 多进程 多线程 传参args 元组传参传参一定要和函数定义的参数顺序保持一致kwargs字典传参字典中的key一定要和参数名保持一致。 顺便随便。元组为一个元素时记得后面要有个 ,my_tuple (‘KEY’,)获取进程编号获取当前进程编号 整数 os.getpid()获取当前父进程编号 整数 os.getppid()子进程守护默认主进程执行完不会终止程序而是等待所有子进程执行完毕才能终止sub_process.daemon True, 这个子进程会守护就是主进程终止不需要等待这个子进程执行完便可终止这跟.NET 多进程效果一样。主进程终止程序就终止了创建子进程时指定daemonTrue或者sub_process.daemonTrue线程和进程区别创建进程的的资源开销要比创建线程的资源开销大每个进程里面至少存在一个线程进程是操作系统资源分配的基本单位、线程是CPU调度的基本单位frommultiprocessing importProcessli[aa]# 这个列表在主进程中defwrite():foriinrange(10):li.append(i)# 这是在子进程 p1 中修改自己的liprint(li)# p1 进程中的 li:[aa,0,1,2,...]defread():print(li)# 这是在子进程 p2 中打印自己的 li只有[aa]if__name____main__:p1Process(targetwrite)p2Process(targetread)p1.start()p1.join()# 等待 p1 执行完 p2.start()# p2 读取的是自己的内存空间不是 p1 修改后的# 输出:# [aa, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (p1的输出)# [aa] (p2的输出)# 使用 multiprocessing.Manager 共享数据frommultiprocessingimportProcess,Managerdefwrite(shared_list):foriinrange(10):shared_list.append(i)print(fwrite进程中的列表: {shared_list})defread(shared_list):print(fread进程中的列表: {shared_list})if__name____main__:# 创建共享列表managerManager()limanager.list([aa])p1Process(targetwrite,args(li,))p2Process(targetread,args(li,))p1.start()p1.join()p2.start()p2.join()print(f主进程中的列表: {li})# 输出:# write进程中的列表: [aa, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# read进程中的列表: [aa, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 主进程中的列表: [aa, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 使用 Queue 传递数据frommultiprocessingimportProcess,Queuedefwrite(q):li[aa]foriinrange(10):li.append(i)q.put(li)# 将结果放入队列defread(q):liq.get()# 从队列获取数据print(li)if__name____main__:qQueue()p1Process(targetwrite,args(q,))p2Process(targetread,args(q,))p1.start()p1.join()p2.start()p2.join()# 输出: [aa, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]分布式进程ThreadLocalThreadLocal 是一种线程局部存储Thread-Local Storage, TLS 机制。简单说它让你在不同线程中拥有相互隔离的变量副本——每个线程访问到的都是自己的那份数据互不干扰。importthreadingimporttime# 创建一个 ThreadLocal 对象local_datathreading.local()defworker(name):# 为当前线程设置属性local_data.usernameprint(f线程{name}设置 user {local_data.user})# 模拟一些操作time.sleep(0.1)# 再次读取仍然是刚才设置的值print(f线程{name}再次读取 user {local_data.user})# 创建多个线程t1threading.Thread(targetworker,args(Alice,))t2threading.Thread(targetworker,args(Bob,))t1.start()t2.start()t1.join()t2.join()线程 Alice 设置 userAlice 线程 Bob 设置 userBob 线程 Alice 再次读取 userAlice 线程 Bob 再次读取 userBob 可以看到两个线程各自操作的 local_data.user 是完全隔离的。线程通信## 1. 共享变量 锁threading.Lock 最推荐的线程间通信方式无需手动加锁。importthreading shared_data0lockthreading.Lock()defworker():globalshared_datafor_inrange(10000):withlock:shared_data1t1threading.Thread(targetworker)t2threading.Thread(targetworker)t1.start();t2.start()t1.join();t2.join()print(shared_data)# 20000# 2. queue.Queue线程安全队列importthreading,queue qqueue.Queue()defproducer():foriinrange(5):q.put(i)q.put(None)# 结束信号defconsumer():whileTrue:itemq.get()ifitemisNone:breakprint(item)threading.Thread(targetproducer).start()threading.Thread(targetconsumer).start()# 3. 事件threading.Event 用于线程间的信号通知一个线程等待另一个线程的“标志”。importthreading eventthreading.Event()defwaiter():event.wait()# 阻塞直到 event.set()print(Go!)defsetter():importtime time.sleep(2)event.set()threading.Thread(targetwaiter).start()threading.Thread(targetsetter).start()进程通信IPC进程不共享内存不能直接访问对方变量。Python 的 multiprocessing 模块提供了多种 IPC 机制。# 1. multiprocessing.Queue 类似 queue.Queue但数据会通过 pickle 序列化后在进程间传递。frommultiprocessingimportProcess,Queuedefworker(q):q.put(Hello from child)if__name____main__:qQueue()pProcess(targetworker,args(q,))p.start()print(q.get())# Hello from childp.join()# 2. multiprocessing.Pipe 返回一对连接对象conn1, conn2 是一对 一对 类似双向管道。比 Queue 更轻量。frommultiprocessingimportProcess,Pipedefchild(conn):conn.send(Hi parent)conn.close()parent_conn,child_connPipe()pProcess(targetchild,args(child_conn,))p.start()print(parent_conn.recv())# Hi parentp.join()# 3. 共享内存multiprocessing.Value / Array 通过共享内存区域实现进程间共享数据需要配合锁避免竞争。frommultiprocessingimportProcess,Value,Lockdefadd(shared_val,lock):for_inrange(1000):# with自动加锁自动释放锁 这比手动调用 lock.acquire() 和 lock.release() 更安全、简洁能避免因忘记释放锁或异常导致锁未释放的问题。withlock:shared_val.value1if__name____main__:vValue(i,0)# i 表示有符号整型lockLock()p1Process(targetadd,args(v,lock))p2Process(targetadd,args(v,lock))p1.start();p2.start()p1.join();p2.join()print(v.value)# 2000# 4. multiprocessing.Manager 提供更高级的共享对象如列表、字典、队列等但性能相对较低。frommultiprocessingimportProcess,Managerdefworker(d,key,value):d[key]valueif__name____main__:withManager()asmanager:dmanager.dict()pProcess(targetworker,args(d,name,Alice))p.start()p.join()print(d)# {name: Alice}分布式通信celery