Open tomoya06 opened 4 years ago
os.fork()
:当前进程直接复制,子进程调用时返回0,os.getppid,父进程返回新生子进程的PIDmultiprocess.Process
:进程类,Process(target=run_proc, args=('test',))
multiprocessing.Pool
:进程池subprocess
:执行指令的子进程multiprocess.Queue
multiprocess.Pipe
具体实例参考廖雪峰的多进程教学
threading.Thread
:线程类concurrent.futures.ThreadPoolExecutor
:线程池threading.local()
的介绍。但需要注意加锁:threading.Lock
具体实例参考廖雪峰的多线程教学
协程:aka. 微线程/纤程/Coroutine。协程的作用,是在执行函数A时,可以随时中断,去执行函数B,然后中断继续执行函数A(可以自由切换)。但这一过程并不是函数调用(没有调用语句),这一整个过程看似像多线程,然而协程只有一个线程执行。
Python对协程的支持是通过generator实现的。
参考廖雪峰的python-异步IO
python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。
python里每一个东西都是对象,它们的核心就是一个结构体:PyObject
typedef struct_object {
int ob_refcnt;
struct_typeobject *ob_type;
} PyObject;
PyObject
是每个对象必有的内容,其中ob_refcnt
就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt
就会增加,当引用它的对象被删除,它的ob_refcnt
就会减少。当引用计数为0时,该对象生命就结束了。
优点:简单,实时性 缺点:循环引用问题
标记清除就是用来解决循环引用的问题的。注意只有容器对象才会出现引用循环。
为了追踪容器对象,需要给每个容器对象维护两个额外的指针, 用来将容器对象组成一个链表,指针分别指向前后两个容器对象,方便插入和删除操作。
python解释器(Cpython)维护了两个这样的双端链表,一个链表存放着需要被扫描的容器对象,另一个链表存放着临时不可达对象。在图中,这两个链表分别被命名为”Object to Scan”和”Unreachable”。每一个节点除了有一个记录当前引用计数的变量ref_count还有一个gc_ref变量,这个gc_ref是ref_count的一个副本,所以初始值为ref_count的大小。
gc启动的时候,会逐个遍历”Object to Scan”链表中的容器对象,并且将当前对象所引用的所有对象的gc_ref减一。这一步操作就相当于解除了循环引用对引用计数的影响。
接着,gc会再次扫描所有的容器对象:
第二次遍历的所有对象都遍历完成之后,存在于”Unreachable”链表中的对象就是真正需要被释放的对象。
整体思想:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。
python分了三代(generation 0,1,2):0代表幼年对象,1代表青年对象,2代表老年对象。新对象分配在Gen0。每次GC后存活的对象就会晋升到Gen+1。
gc的扫描在什么时候会被触发呢?答案是当某一世代中被分配的对象与被释放的对象之差达到某一阈值的时候,就会触发gc对某一世代的扫描。值得注意的是当某一世代的扫描被触发的时候,比该世代年轻的世代也会被扫描。
基本语法
数据类型
Number: int、float、bool、complex
面向对象
class Child(Father)
__attr
class Dog(Mammal, RunnableAnimal, BarkableAnimal)
@property / @attr.setter
slots / str / iter / getitem / etc..
__new__
vs__init__
可迭代vs迭代器vs生成器
next()
函数不断调用,直到抛出StopIteration
错误yield
的函数也是一个生成器函数式编程
lambda
*args
为参数列表;**kwargs
为dict;需要放在命名参数之后*
或**
,将列表/元组或dict解包来传参。参考StackOverflow设计模式
两种实现参考这里。一种是改写
__new__
方法,每个类有一个_instance
属性存单例;一种是用装饰器,所有类及其单例以key-value存在一个dict中。命名空间和作用域
命名空间
名称到对象的映射。分三种,从外到内依次为:
查找顺序为:局部-全局-内置
作用域
一个 Python 程序可以直接访问命名空间的正文区域。分四种:
命名空间和作用域的例子参考菜鸟博客