(day30)GIL + 线程相关知识点
目录
昨日内容
进程互斥锁
让并发变成串行,牺牲了效率,包哦挣了数据安全
mutex = Lock()
# 加锁
mutex.acquire()
# 释放锁
mutex.release()
队列
相当于在内存中开辟了一个队列空间,可以存放一堆数据,遵循“先进先出”,管道(阻塞)+锁
q = Queue()
q.put() # 添加数据,若队列满了,卡住
q.put_nowait() # 若队列满了,报错
q.get() # 获取数据,若队列为空,卡住
q.get_nowait() # ,若队列为空,报错
q.empty() # 判断队列是否为空
q.full() # 判断队列是否满了
进程间通信
进程间数据不共享,可以通过队列实现通信
生产者与消费者模型
生产者:生产数据的
消费者:使用数据的
目的:通过队列来实现该模型,解决供需不平衡问题
线程
什么是线程
进程:执行单位
线程:执行单位
注意:只要开启一个进程就会有一个线程,会在进程结束时,一并销毁
为什么使用线程
节省内存资源
- 开启线程
- 开辟一个新的内存空间
- 会自带一个主线程
- 开启线程
- 一个进程可以开启多个线程
- 开启线程的资源远远小于进程
创建线程的两种方式
# 创建方式1
from threading import Thread
def task():
pass
t = Thread(target = task)
t.start()
# 创建方式2
class MyThread(Thread):
def run():
pass
t= MyThread()
t.start()
线程对象的属性
current_thread().name # 获取当前线程名
enumerate() # 获取当前所有线程对象
activeCount() # 获取当前执行线程个数
is_alive() # 判断线程是否存活
线程互斥锁
from threading import Thread
mutex = Lock()
mutex.acquire()
# 被锁线程
mutex.release(
今日内容
GIL全局解释器锁
基于Cpython来研究GIL
- GIL本质上是一个互斥锁
- 阻止同一个进程下多个线程同时执行,即单个进程下的多个线程不能并行,只能并发
- GIL的存在是为了保证线程安全(垃圾回收机制)
注意:多个线程过来执行,一旦遇到IO操作,会立马释放GIL全局解释器锁,
from threading import Thread
import time
number = 100
def task():
global number
number2 = number
time.sleep(1)
nunmer = number2 -1
for i in range(100):
t = Thread(target = task)
t.start()
多线程的作用
计算密集型
单核情况下,优先使用多线程
多核情况下,优先使用多进程
总结:现在大多数电脑都是多核,因此计算密集型使用多进程
from multiprocessing import Process
from threading import Thread
import os,time
def work():
res = 0
for i in range(100000000):
res*=i
if __name__ == '__main__':
l = []
print(os.cpu_count())
start = time.time()
for i in range(4):
p = Process(target = work)
# p = Thread(target = work)
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print(f'{stop-start}')
IO密集型
单核情况下,优先使用多线程
多核情况下,优先使用多线程
总结:IO密集型使用多线程
from multiprocessing import Process
from threading import Thread
import os,time
def work():
time.sleep(2)
print('>>>>>>>>>')
if __name__ == '__main__':
l = []
print(os.cpu_count())
start = time.time()
for i in range(40):
# p = Process(target = work)
p = Thread(target = work)
l.append(p)
p.start()
for p in l:
p.join()
stop = time.time()
print(f'{stop-start}')
在高效执行多个IO密集型的程序:使用多进程+多线程
死锁
死锁现象:两个或两个以上的进程或线程在执行过程中因争夺资源而造成一种互相等待的现象,称为系统处于死锁状态,或者产生了死锁。
import time
from threading import Lock,Thread
mutex1 = Lock()
mutex2 = Lock()
def task():
work1()
work2()
def work1():
mutex1.acquire()
print('拿到锁1')
mutex2.acquire()
print('拿到锁2')
mutex2.release()
print('解开锁1')
mutex1.release()
print('解开锁2')
def work2():
mutex2.acquire()
time.sleep(1)
mutex1.acquire()
print('拿到锁2')
mutex1.release()
print('解开锁1')
mutex2.release()
print('解开锁2')
for i in range(10):
t = Thread(target=task)
t.start()
递归锁(RLock)
内部维护者一个Lock和counter变量,counter记录acquire的次数,release可以使counter次数减1,只有counter为0时,才能被使用
用于解决死锁问题,相当于连环锁,要么不用,要么一起拿过去
import time
from threading import RLock,Thread
mutex1 = mutex2= RLock()
def task():
work1()
work2()
def work1():
mutex1.acquire()
print('拿到锁1')
mutex2.acquire()
print('拿到锁2')
mutex2.release()
print('解开锁1')
mutex1.release()
print('解开锁2')
def work2():
mutex2.acquire()
time.sleep(1)
mutex1.acquire()
print('拿到锁2')
mutex1.release()
print('解开锁1')
mutex2.release()
print('解开锁2')
for i in range(10):
t = Thread(target=task)
t.start()
信号量(semaphore)
信号量:内置计数器,每当调用acquire内置计数器-1,调用release内置计数器+1,计数器不能小于0,计数器为0时,acquire会阻塞线程直到其他线程调用release
相当于锁店
import time
from threading import Lock,Thread,Semaphore
sm = Semaphore(10)
def task():
work1()
work2()
def work1():
sm.acquire()
print('拿到锁1')
sm.acquire()
print('拿到锁2')
sm.release()
print('解开锁1')
sm.release()
print('解开锁2')
def work2():
sm.acquire()
time.sleep(1)
sm.acquire()
print('拿到锁2')
sm.release()
print('解开锁1')
sm.release()
print('解开锁2')
for i in range(10):
t = Thread(target=task)
t.start()
线程队列
FIFO队列(Queue())
先进先出
import queue
q=queue.Queue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
结果(先进先出):
first
second
third
'''
LIFO队列(lifoQueue())
后进后出
import queue
q=queue.LifoQueue()
q.put('first')
q.put('second')
q.put('third')
print(q.get())
print(q.get())
print(q.get())
'''
结果(后进先出):
third
second
first
'''
优先级队列(PriorityQueue())
首先根据第一个参数判断ascii表的数值大小
判断第二个参数中的汉字顺序
再判断第二参数中数字--> 字符串数字 ---> 中文
以此类推
import queue
q=queue.PriorityQueue()
#put进入一个元组,元组的第一个元素是优先级(通常是数字,也可以是非数字之间的比较),数字越小优先级越高
q.put((20,'a'))
q.put((10,'b'))
q.put((30,'c'))
print(q.get())
print(q.get())
print(q.get())
'''
结果(数字越小优先级越高,优先级高的优先出队):
(10, 'b')
(20, 'a')
(30, 'c')
'''
(day30)GIL + 线程相关知识点的更多相关文章
- [OS] 线程相关知识点
操作系统中引入进程的目的,是为了描述和实现多个程序的并发执行,以改善资源利用率以及提高系统吞吐量.那为什么还需要引入线程呢?下面我们先来回顾一下什么是进程: 进程有两个基本属性:·资源的拥有者:给每个 ...
- IOS开发涉及有点概念&相关知识点
前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...
- 进程 & 线程相关知识
不管Java,C++都有进程.线程相关的内容.在这里统一整理吧. Python的线程,其实是伪线程,不能真正的并发.下面也有讲. 线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序 ...
- 浅谈C#中的 async await 以及对线程相关知识的复习
C#5.0以后新增了一个语法糖,那就是异步方法async await,之前对线程,进程方面的知识有过较为深入的学习,大概知道这个概念,我的项目中实际用到C#异步编程的场景比较少,就算要用到一般也感觉T ...
- 【Java基础】String 相关知识点总结
String 相关知识点总结 字符串的不可变性 概述 String 被声明为 final,因此它不可继承 在 Java8 中,String 内部使用 char 数组存储数据 public final ...
- UITableView相关知识点
//*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...
- Android开发涉及有点概念&相关知识点(待写)
前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...
- iOS开发Swift篇(02) NSThread线程相关简单说明
iOS开发Swift篇(02) NSThread线程相关简单说明 一 说明 1)关于多线程部分的理论知识和OC实现,在之前的博文中已经写明,所以这里不再说明. 2)该文仅仅简单讲解NSThread在s ...
- IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结
添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...
随机推荐
- 如何编写出高质量的 equals 和 hashcode 方法?
什么是 equals 和 hashcode 方法? 这要从 Object 类开始说起,我们知道 Object 类是 Java 的超类,每个类都直接或者间接的继承了 Object 类,在 Object ...
- Python学习-迭代器、生成器
一.迭代器 1. 可迭代对象 我们知道字符串.列表.元组.字典.集合都可以使用for语句进行循环遍历,然后输出每一个元素,这些都是可迭代对象. 检查对象是否是可迭代对象可以用两种方式去判断: (1)使 ...
- 一个有意思的js块作用域问题
1.问题 首先把问题放出来,昨天看了一个掘友发的一个问题,然后跟我同事一起研究了一下,没找出来是为什么,然后我回来一直在想为什么,然后各种找资料研究,从各个方面找为什么,比如js上下文,作用域,js垃 ...
- Java 多线程练习
题目:某公司组织年会,会议入场时有两个入口,在入场时每位员工都能获取一张双色球彩票,假设公司有100个员工,利用多线程模拟年会入场过程, 并分别统计每个入口入场的人数,以及每个员工拿到的彩票的号码.线 ...
- vue-cli搭建项目引入jquery和jquery-weui步骤详解
vue简介 Vue.js 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合 ...
- 【php中的curl】php中curl的详细解说
本文我来给大家详细介绍下cURL的简单的使用方法,下文我将会给大家详细介绍cURL的高级应用, cURL可以使用URL的语法模拟浏览器来传输数据, FTP, FTPS, HTTP, HTTPS, GO ...
- [ASP.NET Core 3框架揭秘] 跨平台开发体验: Windows [上篇]
微软在千禧年推出 .NET战略,并在两年后推出第一个版本的.NET Framework和IDE(Visual Studio.NET 2002,后来改名为Visual Studio),如果你是一个资深的 ...
- 【转】ICMP协议
1.ICMP出现的原因 在IP通信中,经常有数据包到达不了对方的情况.原因是,在通信途中的某处的一个路由器由于不能处理所有的数据包,就将数据包一个一个丢弃了.或者,虽然到达了对方,但是由于搞错了端口号 ...
- 在 Cocos Creator 中使用 Protobufjs(一)
一. 环境准备 我一直在探索Cocos H5正确的开发姿势,目前做javascript项目已经离不开 nodejs.npm或grunt等脚手架工具了. 1.初始化package.json文件 npm ...
- 一步一步剖析Dictionary实现原理
本文是对c#中Dictionary内部实现原理进行简单的剖析.如有表述错误,欢迎指正. 主要对照源码来解析,目前对照源码的版本是.Net Framwork 4.8,源码地址. 1. 关键的字段和Ent ...