GIL锁,线程池
内容梗概:
1.线程队列
2.线程池
3.GIL锁 1.线程队列
1.1先进先出队列(FIFO)
import queue
q = queue.Queue(3)
q.put(1)
q.put(2)
q.put(3)
try:
q.put_nowait(3)
except queue.Full:
print("放满啦")
print(q.get())
print(q.get())
print(q.get())
try:
q.get_nowait()
except queue.Empty:
print("被掏空啦") 2. 1后进先出队列(LIFO)
import queue
q = queue.LifoQueue(3)
q.put(1)
q.put(2)
q.put(3)
try:
q.put_nowait(3)
except queue.Full:
print("放满啦")
print(q.get())
print(q.get())
print(q.get())
try:
q.get_nowait()
except queue.Empty:
print("被掏空啦") 1.3 优先级队列
import queue
q = queue.PriorityQueue(3)
q.put((1,11))
q.put((3,33))
q.put((2,22)) try:
q.put_nowait((4,44))
except Exception:
print("放满啦")
print(q.get())
print(q.get())
print(q.get())
try:
q.get_nowait()
except queue.Empty:
print("被掏空啦") 2.线程池
2.1 线程池的使用以及进程池创建区别
import time
from multiprocessing import Pool
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
#
def func(n):
time.sleep(1)
return n * n
if __name__ == '__main__':
t_p = ThreadPoolExecutor(max_workers=4) # 线程池
# t_p = ProcessPoolExecutor(max_workers=4) # 进程池
res_lis = []
for i in range(10):
res = t_p.submit(func,i) #异步提交
res_lis.append(res) t_p.shutdown() #相当于close+join 要等子线程跑完再做下一步 for el in res_lis:
# time.sleep(0.2)
print(el.result()) 创建进程的另一种方法(也可用此种方法创建进程)
p_pool = Pool(4)
for i in range(10):
res = p_pool.apply_async(func,args=(i,))
print(res.get()) 2.2 进程池的map方法
import time
from multiprocessing import Pool
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def func(n):
time.sleep(0.5)
return n * n if __name__ == '__main__':
t_p = ThreadPoolExecutor(max_workers=4) res = t_p.map(func, range(10)) #注意和进程池相比,此处Map没有自带close,join需要添加 shutdown()
t_p.shutdown() for i in res:
time.sleep(0.5)
print(i)
print('主线程结束') 2.3 进程池的回调函数 import time
from multiprocessing import Pool
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor def func(n):
time.sleep(0.5)
return n * n
def func1(n):
num = n.result()-1
print(num) if __name__ == '__main__':
t_p = ThreadPoolExecutor(max_workers=4)
t_p.submit(func,5).add_done_callback(func1) 3.GIL锁
GIL: Global Interpreter Lock 全局变量锁 注意:1.GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。
2.在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势(每个进程内都有1个GIL锁,每个线程要争抢GIL锁来拿到解释器的使用权限)
3.GIL并不是Python的特性,Python完全可以不依赖于GIL,只是由于CPython由于历史原因暂时无法摆脱GIL
4.GIL保护的是解释器级的数据,保护用户自己的数据则需要自己加锁处理(保护不同的数据的安全,就应该加不同的锁) 提问:GIL的存在,同一时刻同一进程中只有一个线程被执行,进程可以利用多核,但是开销大,而python的多线程开销小,但却无法利用多核优势,那PYTHON不是白学了? 1.对计算来说,cpu越多越好,但是对于I/O来说,再多的cpu也没用,当然对运行一个程序来说,随着cpu的增多执行效率肯定会有所提高(不管提高幅度多大,总会有所提高),
这是因为一个程序基本上不会是纯计算或者纯I/O,所以我们只能相对的去看一个程序到底是计算密集型还是I/O密集型,从而进一步分析python的多线程到底有无用武之地
2.现在的计算机基本上都是多核,python对于计算密集型的任务开多线程的效率并不能带来多大性能上的提升,甚至不如串行(没有大量切换),但是,对于IO密集型的任务效率还是有显著提升的。 总结
应用:
多线程用于IO密集型,如socket,爬虫,web
多进程用于计算密集型,如金融分析
GIL锁,线程池的更多相关文章
- 并发编程-线程-死锁现象-GIL全局锁-线程池
一堆锁 死锁现象 (重点) 死锁指的是某个资源被占用后,一直得不到释放,导致其他需要这个资源的线程进入阻塞状态. 产生死锁的情况 对同一把互斥锁加了多次 一个共享资源,要访问必须同时具备多把锁,但是这 ...
- Java多线程面试题:线程锁+线程池+线程同步等
1.并发编程三要素? 1)原子性 原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行. 2)可见性 可见性指多个线程操作一个共享变量时,其中一个线程对变量 ...
- day34 GIL锁 线程队列 线程池
一.Gil锁(Global Interpreter Lock) python全局解释器锁,有了这个锁的存在,python解释器在同一时间内只能让一个进程中的一个线程去执行,这样python的多线程就无 ...
- CIL锁,GIL与线程池的区别,进程池和线程池,同步与异步
一.GIL锁 什么是GIL? 全局解释器锁,是加在解释器上的互斥锁 GC是python自带的内存管理机制,GC的工作原理:python中的内存管理使用的是应用计数,每个数会被加上一个整型的计数器,表示 ...
- day33 GIL锁 线程队列 线程池
1. 全局解释器锁GIL Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行.虽然 Python 解释器中可 ...
- 并发编程:GIL,线程池,进程池,阻塞,非阻塞,同步,异步
一 GIL(global interpreter lock) GIL中文叫全局解释器锁,我们执行一个文件会产生一个进程,那么我们知道进程不是真正的执行单位,而是资源单位,所以进程中放有解释器(cpy ...
- python 多线程 及多线程通信,互斥锁,线程池
1.简单的多线程例子 import threading,timedef b_fun(i): print "____________b_fun start" time.sleep(7 ...
- 线程GIL锁 线程队列 回调函数
----------------------------------无法改变风向,可以调整风帆;无法左右天气,可以调整心情.如果事情无法改变,那就去改变观念. # # ---------------- ...
- python并发编程之线程(创建线程,锁(死锁现象,递归锁),GIL锁)
什么是线程 进程:资源分配单位 线程:cpu执行单位(实体),每一个py文件中就是一个进程,一个进程中至少有一个线程 线程的两种创建方式: 一 from threading import Thread ...
随机推荐
- CentOS7.2 问题收集 查看文件大小 查看端口
1.在vmware中使用nat模式安装centos7.2,没有ifconfig命令? yum upgrade yum install net-tools 2.查看当前目录所有文件大小 [root@lo ...
- IDEA查看一个类的所有继承关系
通常一个.java文件对应一个java类. 鼠标右击一个类: 即可查看.按住alt键可放大. 另一快捷键:光标在类名上,ctrl+H
- DataTabel 与DataView之间的转化
DataTable转为DataView,或者反之转化, 使用的是文档/试图模型,DataTable可以有多个视图,这样就可以不需要借助List类型对dataTable数据进行筛选或者排序 //Data ...
- Awesome Torch
Awesome Torch This blog from: A curated list of awesome Torch tutorials, projects and communities. T ...
- PredNet --- Deep Predictive coding networks for video prediction and unsupervised learning --- 论文笔记
PredNet --- Deep Predictive coding networks for video prediction and unsupervised learning ICLR 20 ...
- [CodeForces - 276A] Lunch Rush
题目链接:http://codeforces.com/problemset/problem/276/A 从这n个输入中求最大值,注意 和 k的比较,定义一个maxn,对每个输入进行计算即可. AC代码 ...
- 高级定时器TIM1&TIM8
高级定时器 初识stm32高级定时器: (1)高级控制定时器(TIM1 和 TIM8)和通用定时器在基本 ...
- HDU 4918 Query on the subtree(动态点分治+树状数组)
题意 给定一棵 \(n\) 个节点的树,每个节点有点权.完成 \(q\) 个操作--操作分两种:修改点 \(x\) 的点权.查询与 \(x\) 距离小于等于 \(d\) 的权值总和. \(1 \leq ...
- Linux下使用wget下载FTP服务器文件
wget -nH -m --ftp-user=your_username --ftp-password=your_password ftp://your_ftp_host/* 使用命令下载ftp上的文 ...
- Images之Dockerfiles
Best practices for writing Dockerfiles This document covers recommended best practices and methods f ...