总结(3)--- 知识总结(内存管理、线程阻塞、GIL锁)

一、Python中是如何进行内存管理的?

  • 垃圾回收:Python不像C++,Java等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对Python而言,对象的类型和内存都是在运行时确定的。这也是为什么我们称Python语言为动态类型的原因
  • 引用计数:Python采用类似Windows内核对象一样的方式来对内存进行管理。每一个对象都维护这一个对指向该对象的引用的计数。当变量呗绑定在一个对象上的时候,该变量的引用计数就是1,系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为0的时候,该对就会被回收
  • 内存池机制Python的内存机制已金字塔行,1,2层主要有操作系统操作 
    • 第0层是c中的malloc,free等内存分配和释放函数进行操作
    • 第1层和第2层是内存池,有Python的接口函数PyMen——Malloc函数实现,当对象小于256K时有该层直接分配内存
    • 第3层是最上层,也就是我们队Python对象的直接操作
  • 在c中如果频繁的调用malloc 与 free时, 是会产生性能问题的,再加上频繁的分配与释放小块的内存会产生碎片,Python在这里主要干的工作有:
    • 如果请求分配的内存在1~256字节之间就使用字节的内存管理系统,否则直接使用malloc
    • 这里还是会调用malloc分配内存,但每次会分配一块大小为256K大块内存。
    • 经由内存池登记的内存到最后还是会回收到内存池,并不会调用c的free释放掉。以便下次使用。对于简单的Python对象,例如数值、字符串,元组采用的是复制的方式,也就是说当将另一个变量B赋值给变量A时,虽然A和B的内存空间仍然相同,但是当A的值发生变化时,会重新给A分配空间,A和B的地址变得不再相同

二、Python中常见的设计模式有哪些?

1. 创建型模式

  • 社会化的分工越来越细,自热在软件设计方面也是如此, 因此对象的创建和对象的使用分开也就成为了必然趋势,因为对象的创建会消耗系统的很多资源,所以单独对对象的创建进行研究,从而能够搞笑的创建对象就是创建型模式要探讨的问题。这里有6个具体的创建型模式可供研究,他们分别是:
    • 简单工厂模式(Simple Factory)
    • 工厂方法模式(Factory Method)
    • 抽象工厂模式(Abstract Factory)
    • 创建者模式(Builder)
    • 原型模式(Prototype)
    • 单例模式(Singleton)

说明:严格来说,简单工厂模式不是GoF总结出来的23种设计模式之一

  • 2、结构型模式
    • 在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成开发人员关注的焦点,因为如何设计对象的结构,继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性等。对象结构的设计很容易出现设计人员水平的高低,这里有7个具体的结构型模式可供研究,他们分别是:
      • 外观模式(Facade)
      • 适配器模式(Asapter)
      • 代理模式(Proxy)
      • 装饰模式(Decorator)
      • 桥模式(Bridge)
      • 组合模式(Composite)
      • 享元模式(Flyweight)
  • 3.行为型模式
    • 在对象节后和对象创建问题都解决之后,就剩下对象的行为问题了,如果对象的行为设计的好,那么对象的行为会更清晰,他们之间的协作效率就会提高,这里有11个具体的行为型模式可供研究,他们分别是:
      • 模板方法模式(Template Method)
      • 观察者模式(Observer)
      • 状态模式(State)
      • 策略模式(Strategy)
      • 职责链模式(Chain of Responsibility)
      • 命令模式(Command)
      • 访问者模式(Visitor)
      • 调停者模式(Mediator)
      • 备忘录模式(Memento)
      • 迭代器模式(Iterator)
      • 解释器模式(Interpreter)

三、什么是线程安全?

线程安全是在多线程的环境下,能够保证多个线程同时执行时程序依旧运行正确,而且要保证对于共享的数据可以由多个线程存取,但是同一时刻只能有一个线程进行存取。 多线程环境下解决资源竞争问题的办法是加锁来保证存取操作的唯一性

四、Gil锁对Python多线程的影响?

GIL的全称是Global Interpreter Lock(全局解释器锁),来源是Python设计之初的考虑,未来数据安全所做的决定。每个CPU在同一时间只执行一个线程。(在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念、 但并发和并行又有区别,并行是指俩个或者多个时间在同一时刻发生;而并发是指俩个或者多个事件在同一时间间隔内发生)

在Python多线程下,每个线程的执行方式:

  1. 获取GIL
  2. 执行代码直到sleep或者是Python虚拟机将其挂起
  3. 释放GIL

可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是"通行证", 并且在一个Python进程中,GIL只用一个,拿不到通行证的线程,就不允许进入CPU执行

在Python2.x里,GIL的释放逻辑是当前线程遇见IO操作或者ticks技术达到100 进行释放,而且每次释放GIL锁,线程进行锁竞争、切换线程,会消耗资源。并且由于GIL锁存在,Python里一个进程永远只能同时执行一个线程(拿到GIL的线程才能执行)

IO密集型代码(文件处理、网络爬虫等) 多线程能够有效提升效率(单线程下有IO操作会进行IO等待,造成不必要的时间浪费,而开启多线程能做线程A等待时,自动切换到线程B,可以不浪费CPU资源,从而能提升程序执行效率),所以多线程对IO密集型代码比较友好

五、什么是阻塞? 什么是非阻塞?

阻塞调用时这调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。有人也许会把阻塞调用和同步调用等起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已,例如,我们在socket中调用receive函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息,如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中调用,其实主界面还是应该可以刷新。socket接收数据的另一个函数recv则是一个阻塞调用的例子,当socket工作在阻塞模式的时候,如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止

非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回

六、软连接和硬链接的区别?

软连接类似Windows的快捷方式,当删除源文件,那么软连接失效。硬链接可以理解为源文件一个别名。多个别名所代表的是一个同一个文件。rm一个文件的时候,那么此文件的硬链接数减一,当硬链接数为0的时候,文件删除

七、单例模式的应用场景有哪些?

单例模式应用的场景一般发现在一下条件下:

(1) 资源共享的情况下,避免由于资源操作时导致性能活损耗等。如日志文件,应用配置。

(2)控制资源的情况下,方便资源之间的相互通信。如线程池等。

  • 网站的计数器
  • 应用配置
  • 多线程池
  • 数据库配置,数据库连接池
  • 应用程序的日志应用
时间: 2024-11-06 11:27:53

总结(3)--- 知识总结(内存管理、线程阻塞、GIL锁)的相关文章

Python 线程----线程方法,线程事件,线程队列,线程池,GIL锁,协程,Greenlet

主要内容: 线程的一些其他方法 线程事件 线程队列 线程池 GIL锁 协程 Greenlet Gevent 一. 线程(threading)的一些其他方法 from threading import Thread import threading import time def work(): time.sleep(1) print("子线程对象>>>", threading.current_thread()) # 子线程对象 print("子线程名称>

操作系统:内存管理(概念)

对于计算机系统而言,操作系统充当着基石的作用,它是连接计算机底层硬件与上层应用软件的桥梁,控制其他程序的运行,并且管理系统相关资源,同时提供配套的系统软件支持.对于专业的程序员而言,掌握一定的操作系统知识比不可少,因为不管面对的是底层嵌入式开发,还是上层的云计算开发,都需要使用到一定的操作系统相关知识. 内存管理有哪几种方式 分段和分页的区别是什么 什么是虚拟内存 什么是内存碎片什么是内碎片什么是外碎片 虚拟地址逻辑地址线性地址物理地址有什么区别 Cache替换算法有哪些 内存管理有哪几种方式

一次由于Java内存管理机制导致的线程异常阻塞之旅

引言 一转眼已经两年多没写多博客了:一转眼也要快工作两三年了:一转眼我又开始写Java代码了.希望自己可以坚持写写博客,总结总结的习惯!加油. 今天在调试代码的时候,发现两个毫不相关的thread用jstack看竟然其中一个在等待另一个的线程持有的锁,很是奇怪.经过研究,是因为Integer类的实现机制导致的. 一.异常阻塞代码 1 package xxx; 2 3 public class TestDeadLock { 4 public static void main(String[] ar

内存管理 进程 线程

 进程.线程.内存管理是一个内核最基本的服务,也是一个内核最主要的组成部分.这几方面的知识是一个软件开发人员必须掌握的基础知识.虽然一个人不懂这些知识也能编写简单的程序,但这样的程序只能算是皮毛.掌握了进程.线程和内存管理方面的知识,就能够充分利用操作系统内核提供的服务,提高你编写的软件的执行效率.更节省资源.更健壮.顺便说一下,在Windows CE.net下可以运行用Visual Studio.net开发的.net平台上运行的软件,但这样的软件是最上层的软件,离操作系统内核太远了.不但执

每个Android开发者必须知道的内存管理知识

原文:每个Android开发者必须知道的内存管理知识 拷贝在此处,以备后续查看. 相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确实是一门必不可少的能力.今天我们就谈谈在Android平台下内存的管理之道,开始今天的主题之前,先再次回顾两个概念. 内存泄漏:对象在内存heap堆中中分配的空间,当不再使用或没有引用指向的情况下,仍不能被GC正常回收的情况.多数出现在不合理的编码情况下,比如在 Activity中注册了一个广播接收

【iOS开发-33】学习手动内存管理临时抛弃ARC以及retain/assign知识——iOSproject师面试必考内容

我们为什么须要内存管理?当使用内存达到40M和45M时候会发出警告,假设不处理,占用内存达到120M时直接强制关闭程序. 所以出现闪退除了是程序出现逻辑错误,还有可能是内存使用过大. (1)创建一个对象的过程:先分配内存空间存储对象:初始化成员变量:返回对象的指针. (2)对象在创建时,内部会自己主动创建一个引用计数器retainCount,当retainCount=0时,系统会回收当前对象,retainCount是唯一推断标记.release会-1.retain会+1,retain后返回的是自

线程基础知识系列(二)线程的管理

本篇是线程基础知识系列的第二篇,主要简单江夏线程管理相关知识点. 线程基础知识系列(一)线程的创建和启动:说明了线程的2种创建和启动,join(),daemon线程,Callable 任务. 本文的主要内容 线程的状态 线程的优先级 sleep vs wait 线程的流程控制 Interrupt yield让出你的CPU 1.线程的状态 以<线程基础知识系列(一)线程的创建和启动>这张图,是程序的运行时线程信息截图.有main线程,user Threads,daemon Threads.现在咱

操作系统中作业、线程、进程、内存管理、垃圾回收以及缓存等概念

作业:用户在一次解题或是一个事务处理过程中要求计算机系统所做的工作的集合.它包括用户程序.所需要处理的数据以及控制命令等.作业是由一系列有序的步骤组成. 进程:一个程序在一个数据集合的一次运行过程.所以一个程序在不同数据集合上运行,乃至一个程序在同样的数据集合上的多次运行都是不同的进程. 线程:线程是进程中的一个实体,被系统独立调度和执行的基本单位. 管程:管程实际上是定义了一个数据结构和在该数据结构上的能为并发进程做执行的一组操作,这组操作能同步进程和改变管程中的数据. 操作系统中作业.线程.

【转】C语言知识整理(3):内存管理(详细版)

原文链接:http://www.cnblogs.com/yif1991/p/5049638.html 在计算机系统,特别是嵌入式系统中,内存资源是非常有限的.尤其对于移动端开发者来说,硬件资源的限制使得其在程序设计中首要考虑的问题就是如何有效地管理内存资源.本文是作者在学习C语言内存管理的过程中做的一个总结,如有不妥之处,望读者不吝指正. 一.几个基本概念 在C语言中,关于内存管理的知识点比较多,如函数.变量.作用域.指针等,在探究C语言内存管理机制时,先简单复习下这几个基本概念: 1.变量:不