
python进阶--多线程
3.1 使用
3.2 使用
发布日期:2021-05-14 12:22:38
浏览次数:20
分类:精选文章
本文共 4848 字,大约阅读时间需要 16 分钟。
多线程与多进程的比较与多线程应用
文章目录
1. 多线程 vs 多进程
- 多线程: 一个进程的独立运行片段,一个进程可以由多个线程
- 多进程: 程序运行的一个状态,包含地址空间,内存,数据栈等
- 线程与进程的区别: 线程是进程的一种轻量化形式,共享数据与上下文
2. 全局解释器锁(GIL)
- GIL:在CPython中,解释器的全局锁,保证单线程执行
- Python多核性能问题:GIL导致多线程无法充分利用多核资源
- IO密集型任务:适合使用多线程,如网络、磁盘IO等
3. Python多线程实践
3.1 使用 _thread
包
import _threaddef loop1(in1): time.sleep(4)def loop2(in1, in2): time.sleep(2)# 启动多线程_thread.start_new_thread(loop1, ("王老大",))_thread.start_new_thread(loop2, ("王大鹏", "王晓鹏"))
3.2 使用 threading
包
import threadingt1 = threading.Thread(target=func1)t2 = threading.Thread(target=func2)t1.start()t2.start()# 等待子线程结束t1.join()t2.join()print(threading.activeCount())
3.3 守护线程
import threadingdef func(): print("start fun") time.sleep(2) print("end fun")# 非守护线程t1 = threading.Thread(target=func)t1.start()print("main thread end")# 守护线程t2 = threading.Thread(target=func)t2.setDaemon(True)t2.start()print("main thread end")
4. 多线程的共享与同步
4.1 线程共享问题
import threadingsum = 0n = 1000000# 非安全共享t1 = threading.Thread(target=Add)t2 = threading.Thread(target=Minu)t1.start()t2.start()t1.join()t2.join()print(sum)
4.2 线程互斥锁
import threadinglock = threading.Lock()sum = 0n = 1000000# 安全共享def Add(): for i in range(n): lock.acquire() sum += 1 lock.release()def Minu(): for i in range(n): lock.acquire() sum -= 1 lock.release()t1 = threading.Thread(target=Add)t2 = threading.Thread(target=Minu)t1.start()t2.start()t1.join()t2.join()print(sum)
5. 常见线程问题
5.1 线程死锁
import threadingimport timelock_1 = threading.Lock()lock_2 = threading.Lock()def func_1(): print("func_1:申请锁1...") lock_1.acquire() print("func_1:申请锁2...") try: lock_2.acquire() print("func_1:运行中...") time.sleep(2) finally: lock_1.release()def func_2(): print("func_2:申请锁2...") lock_2.acquire() print("func_2:申请锁1...") try: lock_1.acquire() print("func_2:运行中...") time.sleep(4) finally: lock_2.release()# 定时启动线程t1 = threading.Thread(target=func_1)t2 = threading.Thread(target=func_2)t1.start()t2.start()
6. 线程的拓展
6.1 Semaphore(信号量)
import threadingimport timesemaphore = threading.Semaphore(3)def func(): if semaphore.acquire(): print(threading.current_thread().name + "获取信号量") time.sleep(2) semaphore.release() print(threading.current_thread().name + "释放信号量")# 启动8个线程for i in range(8): t = threading.Thread(target=func) t.start()
6.2 Timer(定时任务)
import threadingimport timedef func(): print("I am running.........") time.sleep(4) print("I am done......")if __name__ == "__main__": timer = threading.Timer(6, func) timer.start() i = 0 while True: print(str(i) + "***************") time.sleep(3) i += 1
7. GIL与多线程性能
- GIL:CPython中的全局解释器锁,限制了多线程的执行
- 适用场景:
- CPU密集型任务:不适合,GIL导致多线程效率低
- IO密集型任务:适合,IO任务可以有效分摊到多个线程
8. Python多线程的实际应用
import threadingfrom time import sleep, ctimeclass ThreadFunc: def __init__(self, name): self.name = name def loop(self, nloop, nsec): print(f'Start loop {nloop} at {ctime()}') sleep(nsec) print(f'Done loop {nloop} at {ctime()}')def main(): print(f'Starting at: {ctime()}') t1 = threading.Thread(target=ThreadFunc().loop, args=("LOOP1", 4)) t2 = threading.Thread(target=ThreadFunc().loop, args=("LOOP2", 2)) t1.start() t2.start() t1.join() t2.join() print(f'ALL done at: {ctime()}')if __name__ == "__main__": main()
9. 线程共享与安全性
- 共享资源的非安全性
import threadingsum = 0n = 1000000def Add(): global sum, n for i in range(n): sum += 1def Minu(): global sum, n for i in range(n): sum -= 1t1 = threading.Thread(target=Add) t2 = threading.Thread(target=Minu)t1.start() t2.start() t1.join() t2.join() print(sum)
- 使用互斥锁
import threadingsum = 0n = 1000000lock = threading.Lock()def Add(): for i in range(n): lock.acquire() sum += 1 lock.release()def Minu(): for i in range(n): lock.acquire() sum -= 1 lock.release()t1 = threading.Thread(target=Add) t2 = threading.Thread(target=Minu)t1.start() t2.start() t1.join() t2.join() print(sum)
10. 线程特殊情形:可重入锁
import threadingimport timeclass MyThread(threading.Thread): def run(): global num time.sleep(1) if mutex.acquire(1): num += 1 msg = self.name + ' set num to ' + str(num) print(msg) time.sleep(1) mutex.acquire() time.sleep(1) mutex.release() num = 0num = 0mutex = threading.RLock()def testTh(): for i in range(5): t = MyThread() t.start()
这篇文章详细介绍了Python多线程的实现与使用方法,包括线程与进程的区别、多线程的同步与共享问题、线程的高级特性(如互斥锁、可重入锁、信号量等),以及Python线程的实际应用场景。
发表评论
最新留言
关注你微信了!
[***.104.42.241]2025年05月05日 08时14分32秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
主线程中Looper的轮询死循环为何没有阻塞主线程?
2019-03-11
Gradle实战四:Jenkins持续集成
2019-03-11
使用RestTemplate,显示请求信息,响应信息
2019-03-11
wgcloud运维监控系统错误:防篡改校验错误次数大于10次,不再上报数据
2019-03-11
为什么WGCLOUD安装完后,启动服务端打不开网页
2019-03-11
iOS 开发官方文档链接收集
2019-03-11
linux学习笔记(四)基本用户管理与帮助命令
2019-03-11
小程序:防止父方法被子方法冒泡,使用catchtap
2019-03-11
vue报错 created hook错误
2019-03-11
单选框点击文字也能选中
2019-03-11
此主机支持Intel VT-x,但Intel VT-x 处于禁用状态。
2019-03-11
06-局部变量和全局变量
2019-03-11
12-面向对象1
2019-03-11
解决Vue源码运行错误
2019-03-11
HDU - 4109 Instrction Arrangement
2019-03-11
Lua websocket长连接
2019-03-11
SQL 分页查询 返回总条数
2019-03-11
重写的特点
2019-03-11
C语言_动态内存分配练习
2019-03-11