1. 进程的定义
进程是系统进行资源分配和调度的一个独立单位。
进程拥有自己独立的内存空间,所以进程间数据不共享,创建和销毁进程的开销比较大。
import multiprocessingimport timedef sing():for i in range(89):print('----正在唱歌-----')time.sleep(1)def dance():for i in range(3):print('----正在跳舞-----')time.sleep(89)if __name__ == '__main__':#创建两个进程p1=multiprocessing.Process(target=sing)p2=multiprocessing.Process(target=dance)# 开始执行进程p1.start()p2.start()
进程之间通讯
1).queue队列
2).进程池
队列是一种先进先出的存储数据结构,就比如排队上厕所一个道理。两个进程通讯,就是一个子进程往queue中写内容,另一个进程从queue中取出数据。就实现了进程间的通讯了。
创建 queue队列对象
q = multiprocessing.Queue(maxsize)
参数 :maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。
返回值q 是队列对象。
- put()方法 ,向队列中存放数据。如果队列已满,此方法将阻塞至有空间可用为止。
 - get()返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。
 - get_nowait(): 不等待,直接抛出异常
 - full()如果q已满,返回为True
 - empty() 如果调用此方法时 q为空,返回True。
```python
创建队列
q=multiprocessing.Queue(3)相队列里存放数据
q.put(‘hello’) q.put(123) q.put([1,2,3])获取列表中数据数量
print(q.qsize())判断队列是否存放满了
print(q.full()) 
获取数据
print(q.get()) print(q.get())
不等待
time.sleep(3) print(q.get_nowait())
<a name="T4wtc"></a>## 2. 线程的定义线程是进程的一个实体,是CPU调度和分派的基本单位。<br />线程必须依赖于进程存在。一个进程至少拥有一个线程,叫主线程。而多个线程共享内存,从而极大地提高了运行效率。<a name="XUmih"></a>### 如何避免多线程竞争资源- **加锁**- **使用队列(queue)**<a name="7S7V4"></a>## 3.协程的定义协程则是程序级别的由程序根据需要自己调度。<br />在一个线程中会有很多函数,我们把这些函数称为子程序,在子程序执行过程中可以中断去执行别的子程序,而别的子程序也可以中断回来继续执行之前的子程序,这个过程就称为协程。<br />协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。<a name="82PmJ"></a>### 协程的优点:- 无需线程上下文切换的开销,协程避免了无意义的调度,由此可以提高性能(但也因此,程序员必须自己承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力)- 无需原子操作锁定及同步的开销- 方便切换控制流,简化编程模型- 高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。所以很适合用于高并发处理。<a name="8ny7V"></a>### 协程的缺点:- 无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,协程需要和进程配合才能运行在多CPU上.当然我们日常所编写的绝大部分应用都没有这个必要,除非是cpu密集型应用。- 进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序<a name="A4uFu"></a>## 4.进程、线程、协程之间的区别一个程序至少有一个进程,一个进程至少有一个线程<br />线程是划分尺度较小的进程(资源比进程占用的少),使得多线程程序的并发性高。<br />进程在执行的过程中拥有独立的内存单元,而多个线程共享这块内存空间,从而极大的提高了程序的运行效率。<br />线程不能独立执行,必须依存在进程中。<a name="dMaWN"></a>### 定义的不同- 进程是系统进行资源分配最小单元,线程是调度执行的最小单位。- 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序执行的需要的cpu资源),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源(主要是内存资源).<a name="nWlHi"></a>### 区别- 一个程序至少有一个进程,一个进程至少有一个线程.- 线程的划分尺度小于进程(资源比进程少),使得多线程程序的并发性高。- 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率- 线程不能够独立执行,必须依存在进程中<a name="78102351"></a>### 优缺点线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源的管理和保护;而进程正相反。<a name="jAc5u"></a>## 5.GIL 锁讲到 Python 中的多线程,就不得不面对 GIL 锁,GIL 锁的存在导致 Python 不能有效地使用多线程实现多核任务,因为在同一时间,只能有一个线程在运行。<br />GIL 全称是 Global Interpreter Lock,译为**全局解释锁**。早期的 Python 为了支持多线程,引入了 GIL 锁,用于解决多线程之间数据共享和同步的问题。但这种实现方式后来被发现是非常低效的,当大家试图去除 GIL 的时候,却发现大量库代码已重度依赖 GIL,由于各种各样的历史原因,GIL 锁就一直保留到现在。<a name="crM4a"></a>## 6.内建函数:map/reduce/filtermap/reduce/filter 是 Python 中较为常用的内建高阶函数,它们为函数式编程提供了不少便利。<a name="TjGR1"></a>### mapmap 函数的使用形式如下:<br />map(function, sequence)<br />**解释**:对 sequence 中的 item 依次执行 function(item),并将结果组成一个 List 返回,也就是:<br />[function(item1), function(item2), function(item3), ...]<br />看一些简单的例子。```python>>> def square(x):return x * x>>> map(square, [1, 2, 3, 4]) [1, 4, 9, 16]>>> map(lambda x: x * x, [1, 2, 3, 4]) # 使用 lambda [1, 4, 9, 16]>>> map(str, [1, 2, 3, 4]) ['1', '2', '3', '4']>>> map(int, ['1', '2', '3', '4']) [1, 2, 3, 4]
再看一个例子:
def double(x):     return 2  x def triple(x):     return 3 x def square(x):     return x * x funcs = [double, triple, square]  # 列表元素是函数对象 # 相当于 [double(4), triple(4), square(4)] value = list(map(lambda f: f(4), funcs)) print value # output [8, 12, 16]
上面的代码中,我们加了 list 转换,是为了兼容 Python3,在 Python2 中 map 直接返回列表,Python3 中返回迭代器。
reduce
reduce 函数的使用形式如下:
reduce(function, sequence[, initial])
解释:先将 sequence 的前两个 item 传给 function,即 function(item1, item2),函数的返回值和 sequence 的下一个 item 再传给 function,即 function(function(item1, item2), item3),如此迭代,直到 sequence 没有元素,如果有 initial,则作为初始值调用。
也就是说:
reduece(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
看一些例子,就能很快理解了。
>>> reduce(lambda x, y: x * y, [1, 2, 3, 4])  # 相当于 ((1 * 2) * 3) * 4 24 
>>> reduce(lambda x, y: x * y, [1, 2, 3, 4], 5) # ((((5 * 1) * 2) * 3)) * 4 120 
>>> reduce(lambda x, y: x / y, [2, 3, 4], 72)  #  (((72 / 2) / 3)) / 4 3 
>>> reduce(lambda x, y: x + y, [1, 2, 3, 4], 5)  # ((((5 + 1) + 2) + 3)) + 4 15 
>>> reduce(lambda x, y: x - y, [8, 5, 1], 20)  # ((20 - 8) - 5) - 1 6 
>>> f = lambda a, b: a if (a > b) else b   # 两两比较,取最大值 
>>> reduce(f, [5, 8, 1, 10]) 
10
filter
filter 函数用于过滤元素,它的使用形式如下:
filter(function, sequnce)
解释:将 function 依次作用于 sequnce 的每个 item,即 function(item),将返回值为 True 的 item 组成一个 List/String/Tuple (取决于 sequnce 的类型,python3 统一返回迭代器) 返回。
看一些例子。
>>> even_num = list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5, 6])) 
>>> even_num [2, 4, 6] 
>>> odd_num = list(filter(lambda x: x % 2, [1, 2, 3, 4, 5, 6])) 
>>> odd_num [1, 3, 5] 
>>> filter(lambda x: x < 'g', 'hijack') 'ac'        # python2 
>>> filter(lambda x: x < 'g', 'hijack') <filter object at 0x1034b4080>   # python3
小结
- map/reduce/filter 为函数式编程提供了不少便利,可使代码变得更简洁;
 - 注意在 python2 和 python3 中,map/reduce/filter 的返回值类型有所不同,python2 返回的是基本数据类型,而 python3 则返回了迭代器;
 
