同期および非同期実装
3つの状態が実行されました:ランニング、準備が、ブロックされました
ブロッキング、ノンブロッキング、同期、非同期
- (角度ランニング)をブロッキング:ランニング、IO、プログラムがハングに遭遇し、CPUが切り取ら
- (角度ランニング)ノンブロッキング:プログラムは、IOに遭遇しませんでした。私はIOに遭遇しましたが、いくつかの手段によって、CPUが私のプログラムを実行するように強制しましょう
- 同期(角度がタスクを提出):先生が最初の最初のタスクが本を書い完了したことを告げた:私は(例次のタスクを提出した後、タスクを提出、タスクは、戻り値を返す(IOがあるかもしれない)タスクの終了までから実行し始めました私は場所を待つ、と彼は二日後に完了し、私は次のタスクを公開する、逃げるように言わ...)
- 非同期(角度がタスクを提出):一度に複数のタスクを提出した後、私は、コードの次の行を実行します(例:直接は私私の忙しい私に教えてくれ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): pool.submit(task,i) pool.shutdown(wait=True) #shutdown:让我的主进程等待进程池中所有的子进程都结束任务之后,再执行,有点类似与join #shutdown:在上一个进程池没有完成所有的任务之前,不允许添加新的任务 #一个任务时通过一个函数实现的,任务完成得返回值就是函数得返回值 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() 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('====主')
どのように非同期の結果を得ますか?
最初の方法:制服リサイクル結果
方式一:异步调用,统一回收结果 from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import time import os import random def task(i): print(f'{os.getpid()}任务开始') time.sleep(random.randint(1,3)) print(f'{os.getpid()}任务结束') return i if __name__ == '__main__': l1=[] pool=ProcessPoolExecutor() 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('全') #统一回收结果:我不能马上收到任何一个已经完成任务的返回值,我只能等到所有任务结束统一回收
第二の方法:1つの回復ずつ
import requests def task(url): """模拟的就是爬取多个源代码,一定有IO操作""" ret=requests.get(url) if ret.status_code==200: return ret.text def parse(content): """模拟对数据进行分析 一般没有IO 如果都有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))
非同期コールバックコール+
ブラウザが動作します:正しい場合は、お使いのブラウザを与え、あなたの要求を確認するために、サーバー、サーバーに要求を送信あなたが見る、コード内のファイルはかなり美しいレンダリングされ、ブラウザがファイルを受信し、ファイルを返します。外観
何爬虫類?
- コードを使用してブラウザをシミュレートし、ブラウザは、ソースコードの束のためのワークフローを実行します
- データクレンジングのためのソースコードは、私が欲しいデータを取得します
モジュールリクエストの内部に取り付けられ第3のモジュールにPIPモジュール、
アナログブラウザ
import requests#导入requests模块 ret=request.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 如果有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())) 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): 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=ProcessPoolExecutor(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: print(res.result())
非同期呼び出し+コールバック関数(第3版)
#版本三: #基于异步调用回收所有任务结果我要做实时回收结果 #并发执行任务每个任务只是处理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): 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タイプのコールバックハンドラタイプの非同期処理