python 协程、进程、线程_Python中的进程/线程/协程

在爬虫中的数据下载部分,由于单线程下载非常慢,这里要考虑使用多线程。

1. 进程

1) 在Unix/Linux操作系统里面,系统提供了Fork()调用,跟普通的函数不同,fork调用一次,返回两次。因为操作系统把当前进程(父进程)复制了一份(子进程),所以在父和子进程内分别返回,即返回两次。子进程返回0,父返回子进程的ID.

2)   在windows里面没有fork调用,但是python提供了multiprocessing模块来支持其跨平台性

3) 另外还有进程间通信等等            具体可以参见廖雪峰的网站

2. 线程

一个进程内的多个线程。线程是最小的执行单元。

一般使用threading这个高级模块。

启动一个线程,就是把一个函数传入,创建Thread实例,然后start()执行

python 协程、进程、线程_Python中的进程/线程/协程_第1张图片

运行结果:

python 协程、进程、线程_Python中的进程/线程/协程_第2张图片

可以看到:

首先程序进程运行起来之后,会启动主线程MainThread,current_thread()函数永远返回当前线程的实例,这时候输出第一行;

之后,子进程的名字在创建时指定,由 threading.Thread()创建

3. Lock

多线程之间共享数据,同时更改同一个变量,所以可能把内容搞混乱。

看下面的例子:

python 协程、进程、线程_Python中的进程/线程/协程_第3张图片

这里有两个线程t1和t2,同时都在操作balance,而操作balance需要多个语句,很可能在操作过程中被另外一个线程打断。最终导致结果出错。

所以说,需要加线程锁。

锁的作用就是说在某个线程开始执行change_it时候,因为该线程获得了锁,其他的线程不能同时执行change_it()。不论多少个线程,锁只有一个,所以在某个特定的时刻,执行change_it()的只能是某个特定的线程。

python 协程、进程、线程_Python中的进程/线程/协程_第4张图片

这样就可以保护到变量了。

4. 分布式进程

在多线程和多进程上来看,优先选择多进程,因为process更稳定,而且可以分配到多台机器上去。

python中的multiprocessing 模块支持多进程。其中的manager 子模块还支持把多进程分布到多个机器上。一个服务进程作为调度者,将任务分布到其他多个进程中去,依靠网络进行通信。

参见廖雪峰分布式进程

5. 协程

协程是单个线程执行的。

优势:

1)由于不用线程之间的切换(线程数多时候消耗大),所以与多线程比起来,协程的执行效率非常高。

2) 不需要线程锁。

要利用多核CPU,一般用多进程+协程。   ( 所以看来多线程还是用的比较少的)

在python中,我们一般用第三方库 gevent来支持协程。gevent用到的主要模式是greenlet.

python 协程、进程、线程_Python中的进程/线程/协程_第5张图片

下面看一下运行结果,可以看到,三个函数是并发执行的,但是只有一个线程。

python 协程、进程、线程_Python中的进程/线程/协程_第6张图片

需要注意的是,gevent 在 unix和Linux下都可以高并发的地执行,但是在windows下可能会有报错。

看一下,我们的爬虫代码里面的Gevent实例

ea8c4111f6ba504f18c133966f45c2fc.png

先加入库,

python 协程、进程、线程_Python中的进程/线程/协程_第7张图片

然后在下载图片的地方,看到gevent.spawn(函数名,参数)   把函数变成gevent实例,最后加入实例池即可并行执行。

你可能感兴趣的:(python,协程,进程,线程)