Python并发与并行(2)——线程的启动与停止

虽然表面上看像时同时进行多个线程,但是了解“并发”概念的人都知道,python解释器同一时间还是只允许执行一个线程,因此并不是真正的Parallel处理,只不过“切换速度”快到让人感觉是同时处理罢了。

阻断

有时候很多作业并不能实时完成,需要等待着输入和输出,这时为了更好的利用这段时间,解释器就会尝试执行另一个线程,因此线程的适用场合之一就是非计算密集的场合,趁着等待一个进程输入输出的时间来执行另一个线程。举一个最典型的例子吧,网络爬虫,网络爬虫很大一部分时间都要用来等待网页的响应和输入输出,因此多线程可以大大利用这些时间:

import threading
from urllib.request import urlopen

def download_html(url, file):
    with urlopen(url) as url, open(file,'wb') as f:
        f.write(url.read())

urls=['www.baidu.com','www.sina.com','www.jianshu.com']

filenames = ['1.html','2.html','3.html']

for url, file in zip(urls,filenames):
    t=threading.Thread(target=download_html, args=(url,))
    #Thrad实例的start方法执行时,指定的函数就会独立运行各个线程
    t.start()

然而对于计算密集型任务,使用线程不一定会提高处理效率,很大情况下反而会降低处理效率,因为解释器会因为线程切换而耗费不必要的时间。
我们本节的爬虫属于IO密集型,如果不理解计算密集型或IO密集型的概念,请参考该博客:https://blog.csdn.net/scrat_kong/article/details/84947414

这里再讲一个东西,如果在主线程中启动了额外的线程,默认会等待被启动的所有线程都执行完才会终止程序。然而,如果一个线程Thread在创建时指定了daemon参数为True(threading.Thread(daemon=True)),在所有的非Daemon线程都结束时程序就会直接终止,不会等待Daemon线程执行结束。Daemon()程序的意思就是一直运行的服务端程序,又称为守护进程,通常在系统后台执行一些常驻任务,可以指定daemon端,不与前台进行交互,一般用作系统服务。如果我们需要在后台执行一些常驻任务,可以指定daemon的参数。

你可能感兴趣的:(Python并发与并行(2)——线程的启动与停止)