ブロッキング、ノンブロッキング、同期および非同期
ブロッキングとノンブロッキング
ランニング、準備ができて、ブロックされた:3つの状態が実行中のプロセス
ブロッキングとノンブロッキング:
ブロックされた:ランニング、IO、プログラムがハングを満たし、CPUが切り取ら。
ノンブロッキング:プログラムは、何らかの手段でIO、IOの出会いが、私が遭遇したCPUが私のプログラムを実行することを強制することはできませんでした。
角度のタスクを提出します:
同期:(IOがあるかもしれません)、ミッションの最後まで実行するには、開始からタスクをタスクを提出し、私の提出中のミッションの後に戻り値を返します。
非同期:一度に複数のタスクを提出した後、私は、コードの次の行を実行します。
同期呼び出しおよび非同期呼び出し
同期呼び出し:
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 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)
print('===主')
非同期呼び出しの結果を得るには二つの方法:
モード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()
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('===主')
# 结果:
12708开始任务
8632开始任务
1848开始任务
14544开始任务
10704开始任务
18776开始任务
18480开始任务
18548开始任务
13916开始任务
17144开始任务
1848任务结束
14544任务结束
18548任务结束
8632任务结束
10704任务结束
18480任务结束
13916任务结束
17144任务结束
12708任务结束
18776任务结束
[<Future at 0x232b4a377b8 state=finished returned int>, <Future at 0x232b4a82c88 state=finished returned int>, <Future at 0x232b4a82d30 state=finished returned int>, <Future at 0x232b4a82dd8 state=finished returned int>, <Future at 0x232b4a82e80 state=finished returned int>, <Future at 0x232b4a82f28 state=finished returned int>, <Future at 0x232b4a8d048 state=finished returned int>, <Future at 0x232b4a8d128 state=finished returned int>, <Future at 0x232b4a8d208 state=finished returned int>, <Future at 0x232b4a8d2e8 state=finished returned int>]
0
1
2
3
4
5
6
7
8
9
===主
オプション2:非同期呼び出しのコールバック関数+
非同期コールバックコール+
モジュールを要求します。
ブラウザが動作します: サービスは、お使いのブラウザがファイルを返す与える正しいならば、あなたの要求を確認するためにサーバに要求を送信し、ブラウザがファイルを受信し、あなたは非常に美しいレンダリングされた参照コード内のファイルを外観。
爬虫類の原則:
1.コードの使用は、ブラウザ、ソースコードのパイルのためのブラウザワークフローをシミュレートします。
2.データクレンジングデータのソースコードは、私が欲しいものを手に入れます。
import requests
ret = requests.get('http://www.baidu.com')
if ret.status_code == 200:
print(ret.text)
三つのプロセスのコールバック関数の紹介:
バージョン1:
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import requests
def task(url):
content = requests.get(url)
return content.text
def parse(obj):
return len(obj.result())
if __name__ == '__main__':
pool = ThreadPoolExecutor(4)
url_list = ['http://www.JD.com','http://www.JD.com', 'https://home.cnblogs.com/u/lifangzheng/',
'https://wizardforcel.gitbooks.io/gopl-zh/content/ch0/ch0-01.html', 'https://www.pypypy.cn/#/',
'https://www.liaoxuefeng.com/', 'https://home.cnblogs.com/u/lifangzheng/',
'https://home.cnblogs.com/u/lifangzheng/', 'https://gitee.com/clover16', 'https://gitee.com/clover16']
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()))
# 版本一的两个缺陷:
# 1. 异步发出10个任务,并发的执行,但是统一的接收所有的任务的返回值.(效率低,不能实时的获取结果)
# 2. 分析结果流程是串行,影响效率.
第2の欠点のバージョン2ベースのバージョンから:(改善)
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import requests
def task(url):
content = requests.get(url)
return parse(content.text)
def parse(obj):
return len(obj.result()) # 嵌套函数,并发执行中分析结果,增加了函数的耦合性
# 并发执行任务,每个任务是通过网页获取源码+数据分析,此任务最好是IO阻塞,才能发挥最大的效果
if __name__ == '__main__':
pool = ThreadPoolExecutor(4)
url_list = ['http://www.JD.com','http://www.JD.com', 'https://home.cnblogs.com/u/lifangzheng/',
'https://wizardforcel.gitbooks.io/gopl-zh/content/ch0/ch0-01.html', 'https://www.pypypy.cn/#/',
'https://www.liaoxuefeng.com/', 'https://home.cnblogs.com/u/lifangzheng/',
'https://home.cnblogs.com/u/lifangzheng/', 'https://gitee.com/clover16', 'https://gitee.com/clover16']
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()))
バージョン3:
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import requests
def task(url):
content = requests.get(url)
return content.text
def parse(obj):
print(len(obj.result()))
if __name__ == '__main__':
pool = ThreadPoolExecutor(4)
url_list = ['http://www.JD.com','http://www.JD.com', 'https://home.cnblogs.com/u/lifangzheng/',
'https://wizardforcel.gitbooks.io/gopl-zh/content/ch0/ch0-01.html', 'https://www.pypypy.cn/#/',
'https://www.liaoxuefeng.com/', 'https://home.cnblogs.com/u/lifangzheng/',
'https://home.cnblogs.com/u/lifangzheng/', 'https://gitee.com/clover16', 'https://gitee.com/clover16']
for url in url_list:
obj = pool.submit(task,url)
obj.add_done_callback(parse) # add_done_callback函数无返回值
# 线程发布后,由空闲线程执行回调函数
PS:非同期処理のIOタイプ、非IOコールバックタイプの処理
関係非同期呼び出しとコールバック?
非同期角度受信結果補正角立っ、ジョブ立ち発行:コールバック関数は、更なる処理のために、シーケンス内の各タスクの結果を受信します。
プール+プール+コールバック関数とプロセススレッドは、小さな違いをコールバック:
プロセスプール+コールバック:メインプロセススレッドプール+コールバックが実行するコールバック関数:実行するアイドル・スレッドへの関数のリターン。