Python中的进程/线程/协程

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

1. 进程

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

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

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


2. 线程

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

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

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


            运行结果:


可以看到:

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

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

3. Lock

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

        看下面的例子:

        

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

所以说,需要加线程锁

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


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

4. 分布式进程

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

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

     参见廖雪峰分布式进程


5. 协程

协程是单个线程执行的。

 优势:

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

                    2) 不需要线程锁。

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

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


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


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

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


先加入库,


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值