日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

Python并發編程06 /同步/異步調用/異步調用+回調函數

系統 1747 0

目錄

  • Python并發編程06 /同步/異步調用/異步調用+回調函數
    • 1.如何看源碼
    • 2.昨日回顧
    • 3.阻塞、同步調用、異步調用
      • 3.1概念
      • 3.2異步調用
      • 3.3同步調用
      • 3.4異步如何取結果
    • 4.異步調用+回調函數
      • 4.1瀏覽器工作原理
      • 4.2什么叫爬蟲
      • 4.3異步調用+回調函數

Python并發編程06 /同步/異步調用/異步調用+回調函數

1.如何看源碼

Python并發編程06 /同步/異步調用/異步調用+回調函數_第1張圖片

Python并發編程06 /同步/異步調用/異步調用+回調函數_第2張圖片

2.昨日回顧

          
            #1.遞歸鎖:RLock,同一把鎖,引用一次計數+1,釋放一次計數-1,只要計數不為零,其他線程就搶不到,能解決死鎖問題。
#2.信號量:同一時刻可以設置搶鎖的線程或者進程的數量
#3.GIL鎖:全局解釋器鎖,同一時刻只能一個線程進入解釋器,Cpython解釋器具有的。
#   優點:保證了解釋器的資源數據的安全
#   缺點:單進程的多線程不能利用多核(并行)
#4.GIL鎖與自己的鎖的區別聯系:
#   相同點:都是互斥鎖
#   GIL鎖保證了解釋器數據資源的安全
#   自己的鎖保證的是進程線程中的數據安全
#5.線程池、進程池:控制開啟線程或者進程的數量
#6.IO密集型:單進程的多線程并發
#  計算密集型:多進程并發或者并行
          
        

3.阻塞、同步調用、異步調用

3.1概念

          
            進程運行的三個狀態:運行,就緒,阻塞
執行的角度:
    阻塞:程序運行時,遇到了IO,程序掛起,CPU被切走
    非阻塞:程序沒有遇到IO,程序遇到IO但是通過某種手段,讓CPU強行運行我的程序
提交任務的角度:
    同步:提交一個任務,自任務開始運行直到此任務結束(可能有IO),返回一個返回值之后,我再提交下一個任務
    異步:一次提交多個任務,然后就執行下一行代碼
    返回結果如何回收?
    
#給三個人發布任務:
#同步: 先告知第一個人完成寫書的任務,我從原地等待,等他兩天之后完成了,告訴完事了,我在發布下一個任務......
#異步: 直接將三個任務告知三個人,我就忙我的我,直到三個人完成之后,告知我.    
          
        

3.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):
#         pool.submit(task,i)
# 
#     pool.shutdown(wait=True)
#     # shutdown: 讓我的主進程等待進程池中所有的子進程都結束任務之后,在執行. 有點類似與join.
#     # shutdown: 在上一個進程池沒有完成所有的任務之前,不允許添加新的任務.
#     # 一個任務是通過一個函數實現的,任務完成了他的返回值就是函數的返回值.
#     print('===主')
          
        

3.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()
#     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.4異步如何取結果

          
            方式一: 異步調用,統一回收結果.
# 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('===主')
# 統一回收結果: 我不能馬上收到任何一個已經完成的任務的返回值,我只能等到所有的任務全部結束統一回收.

          
        

4.異步調用+回調函數

4.1瀏覽器工作原理

          
            #向服務器發送一個請求,服務端驗證你的請求,如果正確,給你的瀏覽器返回一個文件
#瀏覽器接收到文件,將文件里面的代碼渲染成你看到的好看的模樣。
          
        

4.2什么叫爬蟲

          
            #1.利用代碼模擬一個瀏覽器,進行瀏覽器的工作流程得到一堆源代碼
#2.對源代碼進行數據清洗得到想要的數據
          
        

4.3異步調用+回調函數

          
            # 版本一:
# 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__':
#     # 開啟線程池,并發并行的執行
#     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. 分析結果流程是串行,影響效率.

版本二: 針對版本一的缺點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
          
        

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 庆安县| 金川县| 博乐市| 镇远县| 鸡东县| 虹口区| 习水县| 贵州省| 博白县| 阜南县| 英吉沙县| 曲阳县| 静安区| 武宣县| 汝州市| 武安市| 郧西县| 特克斯县| 平和县| 西安市| 乌拉特中旗| 遵义市| 定边县| 香格里拉县| 喀什市| 兴和县| 耒阳市| 炉霍县| 金沙县| 西林县| 金溪县| 兴文县| 青海省| 大城县| 新乐市| 彩票| 晴隆县| 尤溪县| 稷山县| 鸡东县| 潞西市|