python學習筆記(十三): 多線程多進程

來源:互聯網
上載者:User

標籤:人做   run   bsp   線程鎖   守護   get   多個   比較   write   

一、線程&進程

對於作業系統來說,一個任務就是一個進程(Process),比如開啟一個瀏覽器就是啟動一個瀏覽器進程,開啟一個記事本就啟動了一個記事本進程,開啟兩個記事本就啟動了兩個記事本進程,開啟一個Word就啟動了一個Word進程。進程是很多資源的集合。

 

有些進程還不止同時幹一件事,比如Word,它可以同時進行打字、拼字檢查、列印等事情。在一個進程內部,要同時幹多件事,就需要同時運行多個“子任務”,我們把進程內的這些“子任務”稱為線程(Thread)。

由於每個進程至少要幹一件事,所以,一個進程至少有一個線程。當然,像Word這種複雜的進程可以有多個線程,多個線程可以同時執行,多線程的執行方式和多進程是一樣的,也是由作業系統在多個線程之間快速切換,讓每個線程都短暫地交替運行,看起來就像同時執行一樣。當然,真正地同時執行多線程需要多核CPU才可能實現。線程是最小的執行單元,而進程由至少一個線程組成。

我們在做事情的時候,一個人做是比較慢的,如果多個人一起來做的話,就比較快了,程式也是一樣的,我們想啟動並執行速度快一點的話,就得使用多進程,或者多線程,在python裡面,多線程被很多人詬病,為什麼呢,因為Python的解譯器使用了GIL的一個叫全域解譯器鎖,它不能利用多核CPU,只能運行在一個cpu上面,但是你在運行程式的時候,看起來好像還是在一起啟動並執行,是因為作業系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務2,任務2執行0.01秒,再切換到任務3,執行0.01秒……這樣反覆執行下去。表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太快了,我們感覺就像所有任務都在同時執行一樣。這個叫做環境切換。

二、多線程,python中的多線程使用theading模組

下面是一個簡單多線程

    import threading    import time    def sayhi(num): #定義每個線程要啟動並執行函數             print("running on number:%s" %num)             time.sleep(3)         if __name__ == ‘__main__‘:        t1 = threading.Thread(target=sayhi,args=(1,)) #產生一個線程執行個體        t2 = threading.Thread(target=sayhi,args=(2,)) #產生另一個線程執行個體        t1.start() #啟動線程        t2.start() #啟動另一個線程

下面是另一種啟動多線程的方式,繼承式

    import threading    import time    class MyThread(threading.Thread):        def __init__(self,num):            threading.Thread.__init__(self)            self.num = num             def run(self):#定義每個線程要啟動並執行函數                 print("running on number:%s" %self.num)                time.sleep(3)         if __name__ == ‘__main__‘:             t1 = MyThread(1)        t2 = MyThread(2)        t1.start()        t2.start()

這兩種方式沒有什麼區別,兩種寫法而已,我個人喜歡用第一種,更簡單一些。

線程等待,多線程在啟動並執行時候,每個線程都是獨立啟動並執行,不受其他的線程幹擾,如果想在哪個線程運行完之後,再做其他動作的話,就得等待它完成,那怎麼等待呢,使用join,等待線程結束

            import threading            import time            def run():                print(‘qqq‘)                time.sleep(1)                print(‘done!‘)            lis = []            for i in range(5):                t = threading.Thread(target=run)                lis.append(t)                t.start()            for t in lis:                t.join()            print(‘over‘)

守護線程,什麼是守護線程呢,就相當於你是一個國王(非守護線程),然後你有很多僕人(守護線程),這些僕人都是為你服務的,一但你死了,那麼你的僕人都給你陪葬。

            import threading            import time            def run():                print(‘qqq‘)                time.sleep(1)                print(‘done!‘)            for i in range(5):                t = threading.Thread(target=run)                t.setDaemon(True)                t.start()            print(‘over‘)

線程鎖,線程鎖就是,很多線程一起在操作一個資料的時候,可能會有問題,就要把這個資料加個鎖,同一時間只能有一個線程操作這個資料。

        import threading        from threading import Lock        num = 0        lock = Lock()#申請一把鎖        def run():            global num            lock.acquire()#加鎖            num+=1            lock.release()#解鎖                lis = []        for i in range(5):            t = threading.Thread(target=run)            t.start()            lis.append(t)        for t in lis:            t.join()        print(‘over‘,num)

下面來個簡單的爬蟲,看下多線程的效果

        import threading        import requests,time        urls  ={            "baidu":‘http://www.baidu.com‘,            "blog":‘http://www.nnzhp.cn‘,            "besttest":‘http://www.besttest.cn‘,            "taobao":"http://www.taobao.com",            "jd":"http://www.jd.com",        }        def run(name,url):            res = requests.get(url)            with open(name+‘.html‘,‘w‘,encoding=res.encoding) as fw:                fw.write(res.text)                        start_time = time.time()        lis = []        for url in urls:            t = threading.Thread(target=run,args=(url,urls[url]))            t.start()            lis.append(t)        for t in lis:            t.join()        end_time = time.time()        print(‘run time is %s‘%(end_time-start_time))                #下面是單線程的執行時間        # start_time = time.time()        # for url in urls:        #     run(url,urls[url])        # end_time = time.time()        # print(‘run time is %s‘%(end_time-start_time))

三、多進程,上面說了Python裡面的多線程,是不能利用多核CPU的,如果想利用多核CPU的話,就得使用多進程,python中多進程使用multiprocessing模組。

    from multiprocessing import Process    import time    def f(name):        time.sleep(2)        print(‘hello‘, name)     p = Process(target=f, args=(‘niu‘,))    p.start()    p.join()

 

python學習筆記(十三): 多線程多進程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.