多线程使用
发布日期:2022-04-11 08:52:51
浏览次数:7
分类:技术文章
本文共 4067 字,大约阅读时间需要 13 分钟。
多线程
# 1. 导入模块import threading# 创建线程(让每一个线程去执行这个函数(有参数就给参数))t = threading.Thread(target=函数名,args=())# 线程开始工作t.start()
多进程
# 导包import multiprocessing# 创建进程(进程创建之后,在进程中还会创建一个线程)t = multiprocessing.Process(target=函数名,args=())#启动线程t.start()代码要放在 中if __name__ == '__main__':在linux系统中没有这句不会报错# 因为linux系统 支持模式fork; win :spawn; mac支持:fork和spawn(但是在python3.8以后默认设置为spawn)python机制导致的问题# 在最开头加一句 更改设置multiprocessing.set_start_method('fork')
多进程开销比多线程大
GIL锁
CPython解释器中的一个全局解释器锁# 让一个进程同一时刻只能由一个线程可以被cpu调用# 想要利用计算机多核优势,让cpu同时处理一些任务,适合用多进程开发(资源开发大)# 不需要利用多核优势,可以用多线程计算密集型: 多进程 大量数据计算io秘密集型:多线程 文件读写,网络数据传输(下载视频)
多线程开发
程序最开始运行的时候,它内部会先创建一个线程,而一个进程里面模式是有一个主线程
主线程会执行完所有代码,不结束(等待子线程)
常用方法
t.start()
# 当前线程准备就绪(等待CPU调度,具体时间由cpu决定)
t.join()
# 等待当前线程的任务执行完毕后,向下继续执行就是主线程遇到t.join()# 主线程等待,直到子线程结束,再向下执行如果有多个子线程t1.start() # t1开始执行t1.join() # t1运行完毕,再往下运行t2.start() # t2开始执行t2.join() # t2运行完毕,再往下运行# 案例 两个线程同步做。cpu在执行任务时,分片机制,cpu会分片的执行,t1执行 几个步骤,t2执行几个步骤,cpu在两个线程中来回切。t1.start()t2.start()t1.join()t2.join()
t.setDaemon(布尔值)
# 守护线程(必须放在start之前)t.setDaemon(True) 设置守护线程。主线程完毕后,子线程也会自动关闭。t.setDaemon(False) 设置非守护线程。主线程等待子线程,子线程执行完毕后,主线程才关闭(默认)。
t.setName() getName()
t.setName() # 案例t = threading.Thread(target=XXX,args=())t.setName('线程1')t.start() setName要放在start之前。不然设置不上getName()name = threading.current_thread().getName()
自定义线程类
import threadingclass MyThread(threading.Thread): def run(self): print('执行此此线程',self._args) t = MyThread(args=(100,))t.start()
线程安全
创建锁
lock_object = threading.RLock()
加锁:
lock_object.acquire()
释放锁
lock_object.release()
# 他们必须用同一把锁谁是第一个到的,谁就把锁申请到了,然后加锁,继续往下执行。而没有申请到这把锁的就要等待。等待加锁的那个释放了。
# 可以基于上下文管理,内部自动执行# acquire 和release# 就和文件操作类似with lock_object: global num for i in range(100): num+=1print(num)
线程锁
一次锁一次解。lock效率高
Lock 同步锁
lock 不支持锁的嵌套# 锁了一次解开,然后再锁lock_object.acquire()...lock_object.release()lock_object.acquire()...lock_object.release()# 死锁(锁一次没解锁又锁)lock_object.acquire()...lock_object.acquire()
RLock 递归锁
# 开发中rlock用的还是比较多import threadinglock = threading.RLock()# A开发了一个函数,可以被其他人调用(有锁)def func(): with lock: pass# B开发函数需要加锁,还要调用func()def process() with lock: print('...') func() # ........此时就会出现多次锁,只有rlock支持 print('...')
死锁
由于竞争资源或者由于彼此通信而造成的一种阻塞现象
lock_object.acquire()lock_object.acquire()...lock_object.release()lock_object.release()
import threading import timelock1 = threading.Lock()lock2 = threading.Lock()def task1(): lock1.acquire() # 获取第一把锁 time.sleep(1) lock2.acquire() print(11) lock2.release() print(111) lock1.release() print(1111)def task2(): lock2.acquire() #获取第二把锁 time.sleep(1) lock1.acquire() print(22) lock1.release() print(222) lock2.release() print(2222)# 如果两个人都不释放锁,就会死锁
线程池
线程不是开的越多越好。开得多可能会导致系统的性能更低了
# 使用线程池 导包from concurrent.futures import ThreadPoolExecutor# 创建了一个线程池,最多维护100个线程pool = ThreadPoolExecutor(100)# 把一个任务交给线程池,让他安排线程帮助取执行# 线程池中如果有空闲线程,则分配一个线程去执行,执行完毕后再将线程交给线程池# 如果没有空闲线程,就等待pool.submit(函数名,参数1,...)
等待线程池的任务执行完毕
pool.shutdown(True)# 等待线程池内的任务执行完毕,再继续执行# 类似于join
add_done_callback(done)
可以做分工,task专门下载,done专门将下载的东西写入本地
future = pool.submit(task,url)future.add_done_callback(done)# 当线程执行完毕,再执行一下done函数# 线程池先去安排一个线程去执行这个任务(task),任务执行完,再执行一下done
练习题
单例模式
面向对象+多线程相关的面试题
class Singleton: instance = None lock = threading.RLock() def __init__(self,name): self.name = name def __new__(cls,*args,**kwargs): # 返回空对象 if cls.instance: return cls.instance with cls.lock: if cls.instance: return cls.instance cls.instance = object.__new__(cls) return cls.instance
总结
1. 简述进程线程的区别以及应用场景
1. 线程是计算机中可以被cpu调度的最小单元(真正在工作)2. 进程是计算机资源分配的最小单元2. (进程为线程提供资源)3. 一个进程可以有多个线程,同一个进程中的线程可以共享此进程中的3. 资源# 由于GIL锁的存在,控制一个进程中同一时刻只有一个线程可以被CPU调度 4. 计算密集型:适合多进程 5. IO密集型:适合多线程
2.GIL锁
GIL锁是cPython解释器特有的一个全局解释器锁。控制一个进程中同一时刻只有一个线程可以被CPU调度同时像列表。字典等常见对象的线程数据安全,也得益于GIL
3.手写单例模式
4. 判断
t = threading.Thread(target = wait)# 默认值。主线程不会终止,等待子线程t.setDaemon(False)# 主线程结束,子线程就结束,不会等待t.setDaemon(True)# 等子线程完了,主线程才能继续t.join()
转载地址:https://blog.csdn.net/qq_43635902/article/details/123352390 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2024年04月10日 16时23分47秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【Android平台】 Alljoyn学习笔记四 Android Core API参考
2019-04-26
【Alljoyn】Alljoyn学习笔记五 AllJoyn开源技术基础概念解析
2019-04-26
【Alljoyn】 Alljoyn学习笔记六 Alljoyn基本概念
2019-04-26
【Alljoyn】 Alljoyn学习笔记七 Alljoyn瘦客户端库介绍
2019-04-26
【Android】Activity生命周期
2019-04-26
【Android】Activity的四种launchMode
2019-04-26
【Android】Activity的task相关
2019-04-26
【Android】 Intent应用详解
2019-04-26
【Android】 Intent详解
2019-04-26
【Android】 常用的Intent
2019-04-26
Android中AsyncTask的简单用法
2019-04-26
【Android】 Android中Log调试详解
2019-04-26
【Android】Android中WIFI开发总结(一)
2019-04-26
【Android】Android中WIFI开发总结(二)
2019-04-26
【Android】Android之WiFi开发应用示例
2019-04-26
【Android】 Android adb常见问题整理
2019-04-26
【Android】 Android体系结构图
2019-04-26
【Android】 Android中spinner下拉列表的使用
2019-04-26
说说在 python 中,如何删除左右两边不需要的字符
2019-04-26
说说如何管理 Spring Boot 中的起步依赖
2019-04-26