day36

it2022-05-09  30

今日总结:

GIL 锁: 全局解释器锁 线程的安全问题:就是几个线程同一时间去抢占资源问题,这样就会导致数据错乱 GIL锁只存在在cpython中,内置的自带锁,每个线程都自带造成的影响 # 首先必须明确执行一个py文件,分为三个步骤 1,从硬盘加载python解释器到内存 2,从硬盘加载py文件到内存 3,解释器解析py文件内容,交给cpu执行 其次要明确的是每当执行一个py文件,就会立即启动一个Python解释器, py文件中的内容本质是字符串,只有在被解释器解释时,才具备语法意义,解释器会将当前代代码解释给系统能识别的执行的代码 开启子线程时,给子线程指定了一个target表示该子线程要处理的任务即要执行的代码。代码要执行则必须交由解释器, 即多个线程之间就需要共享解释器,为了避免共享带来的数据竞争问题,于是就给解释器加上了互斥锁 由于互斥锁的特性,程序串行,保证数据安全,降低执行效率吗,GIL将使得程序效率降低为什么需要GIL 在使用Python中进行编程时,程序员无需参与内存的管理工作,这是因为Python有自带的内存管理机制,简称GC 有了GIL后,多个线程将不可能在同一时间使用解释器,从而保证了解释器的数据安全。GIL的加锁与解锁时机: 当前线程调用解释器时立即进行加锁 解锁: 当前线程遇到IO操作时解锁 当前线程执行时间超出设置的时间时释放GIL 的优点: 保证了CPython中的内存管理是线程安全的 的缺点: 互斥锁的特性使得多线程无法运行总结: Cpython中IO密集任务应该采用多线程,计算密集型因该采用多进程 在io 密集型多用于多线程 速度快 计算密集型多采用进程,速度快GIL 保护的是解释器级别的数据安全你,比如对象的应用技术,垃圾分代数据等等对于程序中自己定义的数据则没有任何的保护,所以当程序中出现了共享自定义数据是就需要自己加锁进程池和线程池 池 表示一个容器 ,本质上就是一个存储进程或线程的列表 池子中存储的如果是IO密集型任务使用线程池 如果是计算密集任务则用进程池 from concurrent.futures import ProcessPoolExecutorimport time, os# 创建进程池,指定最大进程数为3,此时不会创建进程,不指定数量时,默认为cpu的 -数pool = ProcessPoolExecutor(3)def task(): time.sleep(1) print(os.getpid(), "working")if __name__ == '__main__': for i in range(10): pool.submit(task) # 提交任务时立即创建进程 # 任务执行完成后也不会立即销毁进程 time.sleep(2) for i in range(10): pool.submit(task) # 再有新任务时,直接使用之前已经创建好的进程来执行# 线程池的使用from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutorfrom threading import current_thread, active_countimport time,os# 创建线程池,指定最大线程数为3 ,此时不会创建线程,不指定数量时,默认为CPU 核数*5pool= ThreadPoolExecutor(3)print(active_count()) #只有一个主线程def task(): time.sleep(1) print(current_thread().name,"working")if __name__ == '__main__': for i in range(10): pool.submit(task) #第一次提交任务时立即创建线程 time.sleep(2) for i in range(10): pool.submit(task) #再有新任务时直接使用之前已经创建好的线程来执行待续:同步异步

转载于:https://www.cnblogs.com/Fzhiyuan/p/10982393.html


最新回复(0)