### 内置函数
```python
dic = {'a':1,'c':3,'b':2}
dic = sorted(dic.items()) # 内置函数sorted
{k:v for k,v in dic} # 列表推导式
```
### 进程与线程
1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
2. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源,某个进程内的线程其他进程不可见;
4. 调度和切换:线程上下文切换比进程上下文切换要快的多;
***线程和进程都是一种抽象的概念,线程是一种比进程更小的抽象,线程和进程都可用于实现并发。***
![](https://box.kancloud.cn/9a63afb253a0c4f9fae4f0d3704042a3_847x515.png)
#### Thead
- `join`:阻塞主线程
- `start`:启动线程
- `setDaemon`:守护主线程,主线程结束,杀死子进程
- `theading.Lock()`:线程锁
- `lock.acquire()`:获取锁
- `lock.release()`:释放锁
### GIL全局解释锁
> ***Global Interpreter Lock***
> 为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程之间数据一致性和状态同步的困难.为了有效解决多份缓存之间的数据同步时,产生了GIL.
> GIL是全局排他锁.毫无疑问全局锁的存在会对多线程的效率有不小影响。甚至就几乎等于Python是个单线程的程序。
> 从`release GIL`到`acquire GIL`之间几乎是没有间隙的。所以当其他在其他核心上的线程被唤醒时,大部分情况下主线程已经又再一次获取到GIL了。这个时候被唤醒执行的线程只能白白的浪费CPU时间,看着另一个线程拿着GIL欢快的执行着。然后达到切换时间后进入待调度状态,再被唤醒,再等待,以此往复恶性循环。
Python GIL其实是功能和性能之间权衡后的产物,它尤其存在的合理性,也有较难改变的客观因素。从本分的分析中,我们可以做以下一些简单的总结:
* 因为GIL的存在,只有IO Bound场景下得多线程会得到较好的性能
* 如果对并行计算性能较高的程序可以考虑把核心部分也成C模块,或者索性用其他语言实现
* GIL在较长一段时间内将会继续存在,但是会不断对其进行改进
### IPython缺省值
`datetime?` 显示对象的信息
`datetime??` 显示对象源码
`%timeit np.dot(a, a)` 测量任何python语句