1.GIL概念

1. 什么是GIL(为Cpython解释器)
GIL本身就是一把互斥锁. 原理都一样. 都是让并发的线程同一时间只能执行一个
所以有了GIL的存在. 同一进程下的多个线程同一时刻只能有一个能运行. 无法实现并行 -> 意味着无法利用多核优势 -> 多个CPU同时计算
GIL是影响python运行效率慢的原因之一. 但是不影响并发的执行. 只是无法同时利用多个cpu执行计算 GIL可以被比喻成执行权限. 同一进程下的所有线程要想运行代码都要先抢执行权限 2. 为何要有GIL:
因为Cpython中自带的垃圾回收机制不是线程安全的 -> 需要将GIL锁加在Cpython之上. 控制只能有一个线程在执行.
抢到GIL才能去执行 3. 如果使用:
GIL vs 自定义的互斥锁
GIL相当于执行任务. 会在任务无法执行时. 被强迫释放
自定义互斥锁. 即便是无法执行. 也不回自动释放 4. 多线程执行IO密集型任务会大幅提升效率: 多线程发送网络请求
执行CPU密集型任务反而会降低效率. 因为频繁切换切换线程导致无意义的时间消耗.产生CPU颠簸. CPU负责计算.程序出现io什么都做不了 CPU密集型任务可以使用多进程并发 5. 多线程的并发运行:
每个线程都要先执行请求GIL. 当线程阻塞时(例如IO阻塞). 线程释放GIL. 这时另外一个线程开始运行
操作系统将时间分成多个时间片去运行线程. 线程之间切换速度极快. 肉眼看起来就行是同时运行. 其实并不是同时运行
所以多线程只是并发. 看起来同时运行. 并非并行

2.线程queue

# -*- encoding:utf-8 -*-
# @time: 2022/8/7 16:10
# @author: Maxs_hu
import queue # 队列: 先进先出
q = queue.Queue(5)
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get()) # 堆栈: 先进后出
q = queue.LifoQueue(5) # last in first out
q.put(1)
q.put(2)
q.put(3)
print(q.get())
print(q.get())
print(q.get()) # 优先级队列: 数字越小. 优先级越高
q = queue.PriorityQueue()
q.put((-1, 'data1'))
q.put((11, 'data2'))
q.put((200, 'data3'))
print(q.get())
print(q.get())
print(q.get()) # (-1, 'data1')
# (11, 'data2')
# (200, 'data3')

3.线程池

"""
1. 什么时候用池:
池的功能是限制启动的进程数量或线程数
什么时候应该限制???
当并发任务数远远超过了计算机承受能力时. 即无法一次性开启过多的进程数或线程数
就应该用池的概念将开启的进程数或者线程数限制在计算机可承受的范围内 2. 同步vs异步
同步和异步是提交任务的两种方式
同步: 类似于串行. 任务提交后等待返回值返回. 再提交下一个任务(和异步对比...基本不用)
异步: 提交完任务后不会在原地等待. 直接运行下一行代码. 等到任务有返回值后会自动触发回调函数
""" from concurrent.futures import ThreadPoolExecutor # 线程池启动器 concurrent 能够同时发生的
import time # =====程序无返回值时=====
def func(name):
for i in range(10):
print(name, i) if __name__ == '__main__':
with ThreadPoolExecutor(9) as t:
# 直接将三百个submit提交给线程池
for i in range(100):
t.submit(func, "周杰伦") # submit 提交
t.submit(func, "薛之谦")
t.submit(func, "林俊杰") # =====程序有返回值时,且需要输出返回值时===== def func(name, t):
time.sleep(t)
print(f"我叫{name}")
return name def parse(res):
print(res.result()) # 注意要加括号 if __name__ == '__main__':
with ThreadPoolExecutor(3) as t:
t.submit(func, "薛之谦", 3).add_done_callback(parse) # callback返回即执行,但执行顺序是不确定的
t.submit(func, "许嵩", 2).add_done_callback(parse) # 这里自动执行,参数也是自动传递
t.submit(func, "林俊杰", 1).add_done_callback(parse) # =====执行顺序确定的线程池===== def func(name, t):
time.sleep(t)
print(f"my name is {name}")
return name if __name__ == '__main__':
with ThreadPoolExecutor(3) as t:
result = t.map(func, ["薛之谦", "林俊杰", "许嵩"], [2, 1, 3]) # map 映射
for res in result:
print(res) # 返回值有特点,是因为多线程较快
# map的返回值是迭代器
# 打印的结果是有序的,且按照分配任务的顺序进行打印

4.进程池

# -*- encoding:utf-8 -*-
# @time: 2022/8/7 21:27
# @author: Maxs_hu # 调用进程池(无返回值):
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
import os
import time def task(i):
print('%s is running %s' % (os.getpid(), i))
time.sleep(2) if __name__ == '__main__':
with ProcessPoolExecutor(4) as p: # 创建进程池最多并发四个进程
for i in range(10): # 将9个任务交给进程池执行
p.submit(task, i) # 任务提交 # 进程池(有返回值) -> 返回值无序. 如果想要返回值有序. 则需要使用map函数提交任务
def task(i):
print('%s is running %s' % (os.getpid(), i))
time.sleep(2)
return i ** 2 def parse(res):
print(res.result()) if __name__ == '__main__':
with ProcessPoolExecutor(4) as p:
for i in range(10):
p.submit(task, i).add_done_callback(parse) # 任务提交之后出现返回值就会执行回调函数执行parse. 打印返回值
p.submit(task, i).add_done_callback(parse)

GIL和池的概念的更多相关文章

  1. python之路day06--python2/3小区别,小数据池的概念,编码的进阶str转为bytes类型,编码和解码

    python2#print() print'abc'#range() xrange()生成器#raw_input() python3# print('abc')# range()# input() = ...

  2. IT题库9-线程池的概念和原理

    在什么情况下使用线程池? 1.单个任务处理的时间比较短:2.需要处理的任务的数量大: 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销.2.如不使用线程池,有可能造成系统创建 ...

  3. OC学习篇之---数组对象的引用计数问题和自动释放池的概念

    之前一片文章中我们介绍了OC中的两个关键字@property和@synthesize的使用的使用: http://blog.csdn.net/jiangwei0910410003/article/de ...

  4. OSI传输层TCP与UDP协议、应用层简介、socket模块介绍及代码优化、半连接池的概念

    目录 传输层之TCP与UDP协议 应用层 socket模块 socket基本使用 代码优化 半连接池的概念 传输层之TCP与UDP协议 TCP与UDP都是用来规定通信方式的 通信的时候可以随心所欲的聊 ...

  5. 11月16日内容总结——OSI传输层之TCP与UDP协议、应用层简介、socket模块介绍及代码优化、半连接池的概念

    目录 一.传输层之TCP与UDP协议 1.TCP协议(重要) 三次握手建链接(白话版) 三次握手专业版 四次挥手断连接(白话版) 四次挥手专业版 2.UDP协议 3.tcp和udp的对比 二.应用层简 ...

  6. Python学习之GIL&进程池/线程池

    8.6 GIL锁** Global interpreter Lock 全局解释器锁 实际就是一把解释器级的互斥锁 In CPython, the global interpreter lock, or ...

  7. id,is的用法,小数据池的概念及编码知识进阶

    一:id 查询内存地址 name = 'alex' print(id(name)) li = [1,2,3] print(id(li)) 二:is  判断的是内存地址 name1 = 'alex@' ...

  8. 第三十八天 GIL 进程池与线程池

    今日内容: 1.GIL 全局解释器锁 2.Cpython解释器并发效率验证 3.线程互斥锁和GIL对比 4.进程池与线程池 一.全局解释器锁 1.GIL:全局解释器锁 GIL本质就是一把互斥锁,是夹在 ...

  9. GIL 线程池 进程池 同步 异步 阻塞 非阻塞

    1.GIL 是一个全局解释器锁,是一种互斥锁 为什么需要GIL锁:因为一个python.exe进程中只有一份解释器,如果这个进程开启了多个线程都要执行代码 多线程之间要竞争解释器,一旦竞争就有可能出现 ...

  10. GIL 线程池 进程池 同步 异步

    1.GIL(理论 重点)2.线程池 进程池3.同步 异步 GIL 是一个全局解释器锁,是一个互斥锁 为了防止竞争解释器资源而产生的 为何需要gil:因为一个python.exe进程中只有一份解释器,如 ...

随机推荐

  1. Oracle_20200416

    PLSQL 新建普通用户 1.使用system登录 2.File-->NEW-->SQL WINDOW 3.执行语句 --创建用户 --create user 用户名 identified ...

  2. 关于uniapp图片默认的空隙处理方案

    display:block; 或者 display:flex;

  3. javaheima15 递归

    Java File 作用 创建对象定位文件,可以删除.获取文件信息等.但不能读写文件内容. 构建对象的方式 File file = new File("文件/文件/绝对路径/相对路径&quo ...

  4. IT工具知识-08:如何使用Openwrt下的SMB服务(第一次使用时)?

    0.背景知识 使用固件:Lean的R20.5.9由flippy打包 需要软件:ssh客户端(我用的xshell),浏览器(最好是chrome内核) 1.使用教程 1.1 注释掉SAMBA模板中的某条指 ...

  5. 入门文章学习(一)-Beginner Tutorial

    Abstract: 参照"背景知识查阅"一文的学习路径,对几篇文章的学习做了记录.这是"Beginner Tutorial"一文的学习笔记. 文章链接: htt ...

  6. windows电脑设置【定时任务】开机、关机、启动程序

    windows电脑设置[定时任务]开机.关机.启动程序 shutdown -s -t **(延时秒数):关机 shutdown -r -t **(延时秒数):重启 gina -s -t 36 (开机) ...

  7. PyTorch中的矩阵乘法

    1. 二维矩阵乘法   , 其中 , , 输出 的维度是.该函数一般只用来计算两个二维矩阵的矩阵乘法,而且不支持broadcast操作. 2. 三维带Batch矩阵乘法  由于神经网络训练一般采用mi ...

  8. 通过Dnsmasq自建干净的DNS服务

    不晓得为撒,用网上的一些公共DNS服务的时候,总是莫名其妙的有些网站无法解析,有时候114能解析,阿里DNS不行或者腾讯DNS不行,导致总是来回切换DNS,很是烦心. 于是就想着自己搭建一个DNS服务 ...

  9. 在POD的ENV中添加POD的信息

    主要用到的参数: - name POD_NAME volumeFrom: fieldRef: fieldPath:   metadata.name - name: POD_IP volumeFrom: ...

  10. java8利用流和lambda表达式对list遍历处理

    java8的lambda表达式提供了一些方便list操作的方法,主要涵盖分组.过滤.求和.最值.排序.去重. 优点: (1) 简洁,跟之前的传统写法对比,能少写不少代码; (2) 易并行计算.尤其适用 ...