python文档学习

115 阅读5分钟

廖雪峰

tuple 是不可变的list,元素不能变,也不能增加或减少元素数量 python 变量是动态变量 func(*(1, 2, 3))func(1, 2, 3) func(**{'a': 1, 'b': 2})func(a=1, b=2) python 简直就是js,有闭包、局部变量 lambda 定义匿名函数

# json 转换 dict 和字符串
json.dumps(dict(name='Bob', age=20, score=88))
'{"age": 20, "score": 88, "name": "Bob"}'

json.loads('{"age": 20, "score": 88, "name": "Bob"}')
{'age': 20, 'score': 88, 'name': 'Bob'}
# 进程、线程
对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程,打开一个Word就启动了一个Word进程。

有些进程还不止同时干一件事,比如Word,它可以同时进行打字、拼写检查、打印等事情。在一个进程内部,要同时干多件事,就需要同时运行多个“子任务”,我们把进程内的这些“子任务”称为线程(Thread)。

线程是最小的执行单元,而进程由至少一个线程组成。如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间

所有线程共享内存,即共享共同进程的变量

Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。多线程的并发在Python中就是一个美丽的梦。 因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执行100条字节码,解释器就自动释放GIL锁,让别的线程有机会执行。这个GIL全局锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即使100个线程跑在100核CPU上,也只能用到1个核。

Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。

但是单进程单核上多线程并发还是有意义的:

多线程应用跑在一个单独的核心:这有意义吗?
在单核机器上是不可能实现真正意义上的并行的。然而,如果你的应用可以从多线程中获益,那在单核机器上跑多线程应用还是有意义的。这种情况下当一个进程使用多线程的时候,即使其中的一个线程在执行比较慢或者阻塞的任务,抢占式多任务机制还是可以让应用保持运行。
比如说你正在开发一个桌面应用,它会从一个很慢的磁盘读取一些数据。如果你只是写了个单线程程序,整个应用在读取数据的时候就会失去响应一直到读取完成:分配给这个唯一线程的 CPU 算力在等待磁盘唤醒的过程中被浪费。当然,操作系统还运行了除此之外的其它很多进程,但是你这个特定应用的运行将不会有任何进展。
让我们重新用多线程的方式思考你的应用。程序的线程 A 负责磁盘访问,线程 B 负责主界面。如果线程 A 由于设备读取慢而卡住,线程 B 仍运行着主界面,从而让你的应用保持响应。这是有可能的,因为有了两个线程,操作系统就可以在它们之间切换分配 CPU 资源,而不会让这个程序因为较慢的线程而卡住。

...

我们知道一个 CPU 核心在同一时间只能执行一条机器指令。机器指令本身是原子的,不幸的是,绝大部分操作都是非原子的。在一些硬件上即使是像 x = 1 这样简单的赋值操作也可能是由多个原子机器指令组成的,这就使赋值操作这个整体本身成为一个非原子操作。

作者:掘金翻译计划
链接:https://juejin.cn/post/6844903811954245639
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# 计算密集型 vs. IO密集型
计算密集型任务的特点是要进行大量的计算,消耗CPU资源。

IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。

os.fork()

参考链接

Linux 操作系统提供了一个 fork() 函数用来创建子进程,这个函数很特殊,调用一次,返回两次,因为操作系统是将当前的进程(父进程)复制了一份(子进程),然后分别在父进程和子进程内返回。子进程永远返回0,而父进程返回子进程的 PID。我们可以通过判断返回值是不是 0 来判断当前是在父进程还是子进程中执行。

在 Python 中同样提供了 fork() 函数,此函数位于 os 模块下。
--------------------- 
作者:kongxx 
来源:CSDN 
原文:https://blog.csdn.net/kongxx/article/details/76549743 
版权声明:本文为博主原创文章,转载请附上博文链接!

运行 os.fork() 后,在父进程和子进程中都开始运行之后的代码。子进程中不再运行os.fork() 之前的代码。

celery

Celery:www.jianshu.com/p/1840035cb… Celery是一个异步任务的调度工具。它是Python写的库,但是它实现的通讯协议也可以使用ruby,php,javascript等调用。