1. 程式人生 > >spider ---- 程序&執行緒+++多程序&多執行緒

spider ---- 程序&執行緒+++多程序&多執行緒

  • 1案例演示:

  • 程序-面向過程

    import time
    from multiprocessing import Process
    
    
    def sing():
        for x in range(1, 6):
            print('你在唱女兒情')
            time.sleep(1)
    
    
    def dance():
        for x in range(1, 6):
            print('你在跳小蘋果')
            time.sleep(1)
    
    
    def main():
        # 建立兩個程序,分別執行一個函式
        p_dance = Process(target=dance)
        p_sing = Process(target=sing)
    
        # 啟動程序,兩個子程序
        p_dance.start()
        p_sing.start()
        # 主程序需要等待子程序結束在結束
        p_dance.join()
        p_sing.join()
    
        print('主程序,子程序全部執行結束')
    
    
    if __name__ == '__main__':
        main()
    
    

    程序-面向物件:

    import time
    from multiprocessing import Process
    
    
    class SingProcess(Process):
        def __init__(self, name):
            super().__init__()
            self.name = name
    
        # 重寫run方法,函式名字為run不能更改
        def run(self):
            for x in range(1, 6):
                print('%s在讀紅樓夢' % self.name)
                time.sleep(1)
    
    
    class DanceProcess(Process):
        def run(self):
            for x in range(1, 6):
                print('你在跳鋼管舞')
                time.sleep(1)
    
    
    def main():
        name = '郭襄'
        p_sing = SingProcess(name)
        p_dance = DanceProcess()
    
        p_sing.start()
        p_dance.start()
    
        p_sing.join()
        p_dance.join()
    
        print("主程序,子程序執行結束")
    
    
    if __name__ == '__main__':
        main()
    

    程序池演示:

    import os
    import random
    import time
    from multiprocessing import Pool
    
    
    def demo(name):
        print('%s---任務正在執行,程序id號---%s' % (name, os.getpid()))
        lt = [1, 2, 3]
        time.sleep(random.choice(lt))
    
    
    def main():
        # 建立程序池 物件
        pol = Pool(3)  # 最多建立3個程序
        # 任務名字列表
        lt = ['楊過', '陽頂天', '獨孤求敗', '雕兄', '虛竹', '段正淳', '段譽', '令狐沖', '周伯通', '金輪法王']
        # 迴圈給池子新增任務
        for name in lt:
            pol.apply_async(demo, args=(name,))
        # 關閉池子不再新增
        pol.close()
        # 主程序等待程序池裡面所有的程序結束之後在結束
        pol.join()
        print('主程序,子程序全部執行結束')
    
    
    if __name__ == '__main__':
        main()
    

     

  • 2、多工
        多個任務同時執行
        生活中:唱歌跳舞、開車手腳並用
        計算機中:瀏覽器、sublime、vnc、錄屏,多個任務都在同時執行
        程式碼中:寫一個段程式碼,一個函式可以稱之為一個任務。
        要想實現多工同時執行:多程序、多執行緒
        四個關鍵字
        同步  執行完任務a才能執行任務b
        非同步  執行任務a的同時也執行任務b
        並行  任務a和任務b真的在同時執行         真非同步
        併發  任務a和任務b在一段時間在同時執行   偽非同步
    3、多程序(process)
        怎麼理解程序?
        在電腦中,啟動一個軟體,系統就會分配一個程序
        在程式碼中,寫好的程式碼沒有執行之前稱之為程式,執行的時候就是一個程序
        以前寫的程式碼都只有一個主程序,需要通過主程序來建立其他的子程序
        程序建立
        (1)面向過程
            p = Process(target=xxx, args=(xxx,))
            target: 程序啟動之後要執行的函式
            args: 主程序給子程序傳遞的引數
            p.start()   啟動程序
            p.join()    讓主程序等待
            os.getpid()  獲取當前程序id號
            os.getppid() 獲取父程序id號
        (2)面向物件
            class MyProcess(Process):
                def run(self):
                    pass
            程序啟動執行run方法,如果需要傳參,需要重寫構造方法,在構造方法中要記得手動呼叫父類的構造方法
        程序之間是否共享區域性變數
            不共享
        程序之間是否共享全域性變數
            不共享
            程序之間不共享任何資料
        程序池
            請問:程序是不是建立的越多越好?
            小例子:比如給一個資料夾,資料夾裡面有100個檔案
            copy(src, dst)
            不是絕對的。要開闢多少個程序拷貝呢?
            開闢5個程序,實現100個檔案的拷貝
            最多開闢5個程序,這個東西我們稱之為程序池
    4、多執行緒(thread)
        如何理解執行緒?
        比如在qq裡面,可以同時語音和視訊,在word裡面,可以同時打字、拼寫檢查
        這些同時執行的就可以理解為執行緒
        多工-多程序、多執行緒
        程序和執行緒的區別
        (1)執行緒屬於程序,一個執行緒只能屬於一個程序,一個程序裡面可以有多個執行緒。
        (2)系統分配資源的基本單位是程序。
        (3)系統排程資源的基本單位是執行緒。
        畫圖理解
        以前的程式只有一個程序,主程序,在這個程序裡面只有一個執行緒,主執行緒
        建立執行緒
        (1)面向過程建立
            t = threading.Thread(target=xxx, name=xxx, args=(xxx,))
            target: 執行緒啟動要執行的函式
            name: 給執行緒起名字   threading.current_thread().name
            args: 主執行緒給子執行緒傳遞引數
            t.start()
            t.join()
        (2)面向物件建立
        執行緒之間是否共享區域性變數
            不共享
        執行緒之間是否共享全域性變數
            共享
        執行緒安全、執行緒同步
            a += 1
            多個執行緒往同一個檔案中寫內容
            鎖,獨自使用,開鎖,
            在操作之前加鎖,然後操作,操作完畢之後,釋放鎖
            上鎖的時候是搶的。
            犧牲了效能。
            from threading import Lock
            # 建立一把鎖, 多個執行緒使用一把鎖
            lock = Lock()
            # 上鎖
            lock.acquire()
            # 釋放鎖
            lock.release()
    5、佇列
        生活中:買火車票,佇列特點:先進先出
        棧:先進後出
        程式中:  from queue import Queue
        q = Queue(5)
        q.put(xxx)  新增元素
        q.get()     獲取元素
        q.full()    判斷佇列是否滿
        q.empty()   判斷佇列是否為空
        q.qsize()   得到佇列中元素的個數
    6、多執行緒爬蟲
        執行緒和佇列,生產者消費者模型
        while 1:
            生產資料
            消費資料

        生產資料執行緒
            資料佇列
        消費資料執行緒

        到爬蟲中
        for page in range(1, 11):
            拼接url,傳送請求,得到響應
                資料佇列
            解析響應,儲存資料