在所有语言中提到并发,一般都是通过两种方式,第一种是单核CPU通过不断交互的使用应用程序来实现伪并发,由于在不同的应用之间的交互频率特别快(一般为100个字节码)我们几乎感觉不到这种变化。另一种是通过多核CPU,同时执行多个任务,开启多个进程也可以。
进程、线程、协程
对于进程和线程的关系:一个进程可以有多个线程,并且同一个进程之间的线程可以共享这个进程的资源。同一个进程的不同线程也可以进行信息交互,但是不同进程之间的线程不可以。
进程和线程他们都属于抢占式的使用资源。而协程就不同了。协程是在多个线程执行时当一个发生I/O阻塞时,立即执行另一个线程。
在Python中可以说没有多线程,因为在Python的早期设计时的操作系统都是单核的在当时设计了Global Interpreter Lock(GIL)目前最常用的Python解释器CPython;GIL要求在同一时刻一个进程中只能有一个线程进入操作系统。所以多线程就变成了串行而非并行。而想要实现并行还可以通过开启多个进程为每一个进程分配一个线程,但是由于开启进程需要耗费大量的内存和其它资源,这种方式不推荐使用;对于多线程的任务还可以使用C语言来开发对应的解决方案。更方便的办法就是使用协程,一个协程也是一个进程下的多个线程,在一个线程在I/O阻塞时,可以快速切换到其他线程,在Python3.5版本配合monkey来使用可以极大的提升线程间切换的速度(在线程间切换时也需要耗费大量的资源和时间)因此是一个不错的选择。
例如:简单的线程爬虫
from gevent import monkey
import gevent
from urllib.request import urlopen
monkey.patch_all()#一个补丁,最大程度的利用IO阻塞的时间
def f(url):
print('GET:%s'%url)
resp = urlopen(url)
data = resp.read()
gevent.joinall([
gevent.spawn(f,'需要爬取得URL'),
gevent.spawn(f,'需要爬取得URL'),
gevent.spawn(f,'需要爬取得URL')
])
领取专属 10元无门槛券
私享最新 技术干货