同步異步

  1. 阻塞,非阻塞,同步,異步html

    進程運行的三個狀態: 運行,就緒,阻塞.編程

    執行的角度:瀏覽器

    ​ 阻塞: 程序運行時,遇到了IO,程序掛起,cpu被切走.併發

    ​ 非阻塞: 程序沒有遇到IO,程序遇到IO可是我經過某種手段,讓cpu強行運行個人程序.app

    提交任務的角度:dom

    ​ 同步: 提交一個任務,自任務開始運行直到此任務結束(可能有IO),返回一個返回值以後,我在提交下一個任務.異步

    ​ 異步: 一次提交多個任務,而後我就直接執行下一行代碼.函數

    ​ 返回結果如何回收?url

    給三個老師發佈任務:線程

    同步: 先告知第一個老師完成寫書的任務,我從原地等待,等他兩天以後完成了,告訴完事了,我在發佈下一個任務......

    異步:

    直接將三個任務告知三個老師,我就忙個人我,直到三個老師完成以後,告知我.

  2. 同步調用,異步調用

    1. 異步調用
    # 異步調用返回值如何接收? 未解決.
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time
    import random
    import os
    
    def task(i):
        print(f'{os.getpid()}開始任務')
        time.sleep(random.randint(1,3))
        print(f'{os.getpid()}任務結束')
        return i
    if __name__ == '__main__':
    
        # 異步調用
        pool = ProcessPoolExecutor()
        for i in range(10):
            pool.submit(task,i)
    
        pool.shutdown(wait=True)
        # shutdown: 讓個人主進程等待進程池中全部的子進程都結束任務以後,在執行. 有點相似與join.
        # shutdown: 在上一個進程池沒有完成全部的任務以前,不容許添加新的任務.
        # 一個任務是經過一個函數實現的,任務完成了他的返回值就是函數的返回值.
        print('===主')
    
    
    # 2. 同步調用
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time
    import random
    import os
    
    def task(i):
        print(f'{os.getpid()}開始任務')
        time.sleep(random.randint(1,3))
        print(f'{os.getpid()}任務結束')
        return i
    if __name__ == '__main__':
    
        # 同步調用
        pool = ProcessPoolExecutor()
        for i in range(10):
            obj = pool.submit(task,i)
            # obj是一個動態對象,返回的當前的對象的狀態,有可能運行中,可能(就緒阻塞),還多是結束了.
            # obj.result() 必須等到這個任務完成後,返回告終果以後,在執行下一個任務.
            print(f'任務結果:{obj.result()}')
    
        pool.shutdown(wait=True)
        # shutdown: 讓個人主進程等待進程池中全部的子進程都結束任務以後,在執行. 有點相似與join.
        # shutdown: 在上一個進程池沒有完成全部的任務以前,不容許添加新的任務.
        # 一個任務是經過一個函數實現的,任務完成了他的返回值就是函數的返回值.
        print('===主')
    
    
    # 3 異步如何取結果???
    # 方式一: 異步調用,統一回收結果.
    
    # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    # import time
    # import random
    # import os
    #
    # def task(i):
    #     print(f'{os.getpid()}開始任務')
    #     time.sleep(random.randint(1,3))
    #     print(f'{os.getpid()}任務結束')
    #     return i
    #
    # if __name__ == '__main__':
    #
    #     # 異步調用
    #     pool = ProcessPoolExecutor()
    #     l1 = []
    #     for i in range(10):
    #         obj = pool.submit(task,i)
    #         l1.append(obj)
    #
    #     pool.shutdown(wait=True)
    #     print(l1)
    #     for i in l1:
    #         print(i.result())
    #     print('===主')
    # 統一回收結果: 我不能立刻收到任何一個已經完成的任務的返回值,我只能等到全部的任務所有結束統一回收.
    
    # 第二種方式:
    from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    import time
    import random
    import os
    
    def task(i):
        print(f'{os.getpid()}開始任務')
        time.sleep(random.randint(1,3))
        print(f'{os.getpid()}任務結束')
        return i
    
    if __name__ == '__main__':
    
        # 異步調用
        pool = ProcessPoolExecutor()
        l1 = []
        for i in range(10):
            obj = pool.submit(task,i)
            l1.append(obj)
    
        pool.shutdown(wait=True)
        print(l1)
        for i in l1:
            print(i.result())
        print('===主')
  3. 異步調用+回調函數

    瀏覽器工做原理, 向服務端發送一個請求,服務端驗證你的請求,若是正確,給你的瀏覽器返回一個文件,
    # 瀏覽器接收到文件,將文件裏面的代碼渲染成你看到的漂亮美麗的模樣.
    
    # 什麼叫爬蟲?
    # 1. 利用代碼模擬一個瀏覽器,進行瀏覽器的工做流程獲得一堆源代碼.
    # 2. 對源代碼進行數據清洗獲得我想要數據.
    
    # import requests
    # ret = requests.get('http://www.baidu.com')
    # if ret.status_code == 200:
    #     print(ret.text)
    
    """
    # 版本一:
    # from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
    # import time
    # import random
    # import os
    # import requests
    #
    #
    # def task(url):
    #     '''模擬的就是爬取多個源代碼 必定有IO操做'''
    #     ret = requests.get(url)
    #     if ret.status_code == 200:
    #         return ret.text
    #
    # def parse(content):
    #     '''模擬對數據進行分析 通常沒有IO'''
    #     return len(content)
    #
    #
    # if __name__ == '__main__':
    #     '''串行 耗費時間長,不可取
    #     ret = task('http://www.baidu.com')
    #     print(parse(ret))
    #
    #     ret = task('http://www.JD.com')
    #     print(parse(ret))
    #
    #     ret = task('http://www.taobao.com')
    #     print(parse(ret))
    #
    #     ret = task('https://www.cnblogs.com/jin-xin/articles/7459977.html')
    #     print(parse(ret))
    #
    #     '''
    #     # 開啓線程池,併發並行的執行
    #     url_list = [
    #         'http://www.baidu.com',
    #         'http://www.JD.com',
    #         'http://www.JD.com',
    #         'http://www.JD.com',
    #         'http://www.taobao.com',
    #         'https://www.cnblogs.com/jin-xin/articles/7459977.html',
    #         'https://www.luffycity.com/',
    #         'https://www.cnblogs.com/jin-xin/articles/9811379.html',
    #         'https://www.cnblogs.com/jin-xin/articles/11245654.html',
    #         'https://www.sina.com.cn/',
    #
    #     ]
    #     pool = ThreadPoolExecutor(4)
    #     obj_list = []
    #     for url in url_list:
    #         obj = pool.submit(task,url)
    #         obj_list.append(obj)
    #
    #     pool.shutdown(wait=True)
    #     for res in obj_list:
    #         print(parse(res.result()))
    # # '''
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    # parse(res.result())
    '''
    # print('===主')
    '''
    # 版本一:
    #     1. 異步發出10個任務,併發的執行,可是統一的接收全部的任務的返回值.(效率低,不能實時的獲取結果)
    #     2. 分析結果流程是串行,影響效率.
    #          for res in obj_list:
    #             print(parse(res.result()))
    '''
    
    # 版本二: 針對版本一的缺點2,改進,讓串行編程併發或者並行.
    # from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
    # import time
    # import random
    # import os
    # import requests
    #
    #
    # def task(url):
    #     '''模擬的就是爬取多個源代碼 必定有IO操做'''
    #     ret = requests.get(url)
    #     if ret.status_code == 200:
    #         return parse(ret.text)
    #
    #
    # def parse(content):
    #     '''模擬對數據進行分析 通常沒有IO'''
    #     return len(content)
    #
    #
    # if __name__ == '__main__':
    #
    #     # 開啓線程池,併發並行的執行
    #     url_list = [
    #         'http://www.baidu.com',
    #         'http://www.JD.com',
    #         'http://www.JD.com',
    #         'http://www.JD.com',
    #         'http://www.taobao.com',
    #         'https://www.cnblogs.com/jin-xin/articles/7459977.html',
    #         'https://www.luffycity.com/',
    #         'https://www.cnblogs.com/jin-xin/articles/9811379.html',
    #         'https://www.cnblogs.com/jin-xin/articles/11245654.html',
    #         'https://www.sina.com.cn/',
    #
    #     ]
    #     pool = ThreadPoolExecutor(4)
    #     obj_list = []
    #     for url in url_list:
    #         obj = pool.submit(task, url)
    #         obj_list.append(obj)
    #     '''
    #     # 1 在開一個線程進程池,併發並行的處理. 再開一個線程進程池,開銷大.
    #     # 2 將原來的任務擴大,
    #     版本一:
    #         線程池設置4個線程, 異步發起10個任務,每一個任務是經過網頁獲取源碼, 併發執行,
    #         最後統一用列表回收10個任務, 串行着分析源碼.
    #     版本二:
    #         線程池設置4個線程, 異步發起10個任務,每一個任務是經過網頁獲取源碼+數據分析, 併發執行,
    #         最後將全部的結果展現出來.
    #         耦合性加強了.
    #         併發執行任務,此任務最好是IO阻塞,才能發揮最大的效果
    #     '''
    #     pool.shutdown(wait=True)
    #     for res in obj_list:  # [obj1, obj2,obj3....obj10]
    #         print(res.result())
    #
    """
    # 版本三:
    # 基於 異步調用回收全部任務的結果我要作到實時回收結果,
    # 併發執行任務每一個任務只是處理IO阻塞的,不能增長新得功能.
    # 異步調用 + 回調函數
    from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
    import time
    import random
    import os
    import requests
    
    
    def task(url):
        '''模擬的就是爬取多個源代碼 必定有IO操做'''
        ret = requests.get(url)
        if ret.status_code == 200:
            return ret.text
    
    
    def parse(obj):
        '''模擬對數據進行分析 通常沒有IO'''
        print(len(obj.result()))
    
    
    if __name__ == '__main__':
    
        # 開啓線程池,併發並行的執行
        url_list = [
            'http://www.baidu.com',
            'http://www.JD.com',
            'http://www.JD.com',
            'http://www.JD.com',
            'http://www.taobao.com',
            'https://www.cnblogs.com/jin-xin/articles/7459977.html',
            'https://www.luffycity.com/',
            'https://www.cnblogs.com/jin-xin/articles/9811379.html',
            'https://www.cnblogs.com/jin-xin/articles/11245654.html',
            'https://www.sina.com.cn/',
    
        ]
        pool = ThreadPoolExecutor(4)
    
        for url in url_list:
            obj = pool.submit(task, url)
            obj.add_done_callback(parse)
    
        '''
        線程池設置4個線程, 異步發起10個任務,每一個任務是經過網頁獲取源碼, 併發執行,
        當一個任務完成以後,將parse這個分析代碼的任務交由剩餘的空閒的線程去執行,你這個線程繼續去處理其餘任務.
        若是進程池+回調: 回調函數由主進程去執行.
        若是線程池+回調: 回到函數由空閒的線程去執行.
        '''
    
    # 異步 回調是一回事兒?
    # 異步站在發佈任務的角度,
    # 站在接收結果的角度: 回調函數 按順序接收每一個任務的結果,進行下一步處理.
    
    # 異步 + 回調:
    # 異步處理的IO類型.
    # 回調處理非Io
相關文章
相關標籤/搜索