前言   

  在写python爬虫的时候遇到了多线程,使用多线程的目的是降低抓取时间。接着我接触了一些IO概念,IO就是Input和Ouput,数据进出CPU的意思。

    数据从网线或网卡进入CPU算Input(get请求得到源码),反之就是Output,这是网络IO。

    数据从硬盘进入CPU也是Input,反过来就是Output(把数据write进文件),这是磁盘IO。

  先不细究IO的原理,只需要知道有IO(IO密集型任务),就用python多线程,提高效率。

概念

ios 多线程的串联并发 多线程和io_多线程

怎么理解线程:

  线程可以是一整个Py程序,也可以是Py文件里的一个函数。如果Py程序或者函数开始执行了,你也可以说线程开始执行了。

上个图

ios 多线程的串联并发 多线程和io_python_02

接下来是并发和并行

ios 多线程的串联并发 多线程和io_数据_03

python的多线程是并发还是并行呢?  答案是并发。

ios 多线程的串联并发 多线程和io_多线程_04

  同一时间还是只干一件事,跟单线程没什么两样,所以有大佬说python的多线程就鸡肋。

不过.....对于IO密集型任务,会大概率遇到阻塞(等待),CPU等待的时候就不做事,相当于浪费了。这里使用多线程就有帮助。

ios 多线程的串联并发 多线程和io_数据_05

挂起、竞争gil的操作是由系统调度的,我们不用管。挂起、竞争、另一个线程开始执行,这个过程会消耗一点时间,称切换时间

  若切换时间<<等待时间 ,则提高了效率;如果切换时间与等待时间差不多,就没什么必要用python所谓鸡肋的多线程了(其他语言不一定)

 

 最后一个重要的概念是主线程、子线程

ios 多线程的串联并发 多线程和io_ios 多线程的串联并发_06

子线程其实就是你要并发(同一时间窗做很多次)的任务,比如get请求和write入文件。

这些任务一般都会写进一个函数func或者类里面,然后两步走

  thread  =  Threading.Thread(target =函数func,args=(参数1,参数2))    #用Thread类包(封装)起来

   thread.start()  #start之后就开始跑了

 

等待,还有一个东西Join()、setDaemon(True)  阻塞和守护线程

 

ios 多线程的串联并发 多线程和io_多线程_07

Join()  ==  当一些任务要先于另一些任务完成的时候,可以用

setDaemon   ==  当你觉得一些线程不重要的时候,可以设置守护线程。

          对于非守护线程,就算主线程执行完了,也要等非守护进程完成才能退出

 实例:一个抢车票的例子