Python 进阶学习笔记之六:多线程编程

本文详细介绍了Python的多线程编程,包括threading模块的使用,如线程本地数据、线程对象、锁对象(Lock和RLock)、条件对象、信号量对象、事件对象、定时器对象、栅栏对象、线程池和事件调度器。通过实例演示了各种同步组件的用法,帮助读者掌握多线程编程中的同步和通信机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 进阶系列笔记文章链接:
Python 进阶学习笔记之一:内置常用类型及方法
Python 进阶学习笔记之二:常用数据类型(上)
Python 进阶学习笔记之三:常用数据类型(下)
Python 进阶学习笔记之四:高效迭代器工具
Python 进阶学习笔记之五:异步 IO
Python 进阶学习笔记之六:多线程编程
Python 进阶学习笔记之七:互联网支持
Python 进阶学习笔记之八:面向对象高级编程
Python 进阶学习笔记之九:IO 编程
Python 进阶学习笔记之十:一般加密支持
Python 进阶学习笔记之十一:日志支持
Python 进阶学习笔记之十二:数据压缩与归档

1. 多线程编程 - threading

在多核服务器上,多线程充分利用多核特性提升效率是很普遍的做法,threading 模块就提供了支持多线程编码的高级 API。threading 模块是在较低级的模块 _thread 基础上建立较高级的线程接口,推荐在 3.7 版本后使用本模块构建普通多线程程序。如果你想让你的应用更好的利用多核计算机的计算性能,推荐你使用 multiprocessing模块或者 concurrent.futures.ProcessPoolExecutor类。但是如果你想同时运行多个I/O绑定任务,线程仍然是一个合适的模型。

先代码示例最基本用法:

import threading
import time

local_param = threading.local()                   # 线程 local 变量是一种能存储当前线程变量的一种容器类型,专门用于多线程变量存储

def do_somthing():
    local_param.name = threading.current_thread().getName()     # 当前代码示例中,可以使用此方法获取当前线程的名称
    print(f"{local_param.name} is doing something...")
    time.sleep(1)
    print("over")

mt = threading.Thread(target=do_somthing, name="n1")               # 一种线程实例话方法
mt2 = threading.Thread(target=do_somthing, name="n2")

mt.start()
mt2.start()

# 输出
n1 is doing something...
n2 is doing something...
over
over
# 用法2
local_param = threading.local()

class MyThread(threading.Thread):
    def run(self):
        name = self.name                                      # 继承 Thread 的方式实现一个线程,可以直接取线程名称
        local_param.name = name
        print(f"{local_param.name} is doing something...")
        time.sleep(1)
        print(f"{name} is over")

t1 = MyThread()
t2 = MyThread()

t1.setName("t1")
t2.setName("t2")

t1.start()
t2.start()

# 输出
n1 is doing something...
n2 is doing something...
over
over

上面示例中就启动了两个线程,具体业务可以拿上面两个写法进行扩展了。下面具体讲解一下原生 线程的一些同步操作工具和语法。

查看模块 threading 的源码文件,查看模块注释可以知道,该模块的设计基于 Java 的线程模型,Python 的 Thread 类只是 Java 的 Thread 类的一个子集;目前还没有优先级,没有线程组,线程还不能被销毁、停止、暂停、恢复或中断。

1.1 线程本地数据

线程本地数据是特定线程的数据。管理线程本地数据,只需要创建一个 local (或者一个子类型)的实例并在实例中储存属性:

mydata = threading.local()
mydata.x = 1

在不同的线程中,实例的值会不同,上面的简例中已经有了基本应用。

1.2 线程对象

线程对象通过 threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)进行实例或者继承它在进行实例,实例后需要调用 start()方法来启动线程,直到线程内部的 run()方法执行完成,它都处于 ‘活跃’ 状态,可以用 is_alive()方法用于检查线程是否存活。Python 3.3 新加入的 daemon参数,用来标记一个线程是否是守护线程。

1.3 上下文管理

上下文管理,也就是 with 语句,在这个模块提供的带有 acquire() 和 release() 方法的对象,都可以被用作 with 语句的上下文管理器,当进入语句块时 acquire() 方法会被调用,退出语句块时 release() 会被调用。因此,以下片段:

with some_lock:
    # do something...

相当于:

some_lock.acquire()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值