同期非同期

非同期の非ブロッキング同期をブロックします

ランニングスリーステート・プロセス:ランニング、準備ができて、ブロックされました

実装の観点の2点とジョブを送信

実行角度

妨害:遭遇IOプログラムは、プログラムがハング、実行されている、CPUが切り取ら

ノンブロッキング:プログラムが何らかの手段でIO、IOの出会いが、私に遭遇していなかった、CPUが私のプログラムを実行するように強制しましょう

角度を提出する作業

同期:タスクを提出し、タスクは復帰後の値を返します(IOがあるかもしれない)、このタスクの終了までに実行するために始めた、私は次のタスクを送信します

非同期:複数のタスクを提出し、私は、コードの次の行を指示します

回復の結果を返す方法?

たとえば、同期および非同期であるかを説明します

同期:

最初の先生が本を書くのタスクの完了を知らせるために、私はまだビンを伝えるために二、三日待った後に完了した後、待って、私は次のタスクを公開します

非同期:

三つの3つのタスクは、直接3人の教師が完了した後、私に言ったまで、私は、私で忙しかった、先生に通知します

同期非同期コード層の分析

1.非同期呼び出し

#  1. 异步调用
#  异步调用返回值如何接收? 未解决
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
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__':
    pool = ProcessPoolExecutor ()
    for i in range(10):
        pool.submit(task,i)
    pool.shutdown(wait = True)
    #shutdown 让我的主进程等待进程池中所有的子进程都结束任务后
    #再执行,有点类似于 join
    # 在上一个进程池没有完成所有的任务之前,不允许添加新的任务
    # 一个任务是通过函数实现的,任务完成了他的返回值就是函数的返回值

    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)
    print('===主')
    
    
   结果是一个一个来的

3.どのように非同期リターン結果

方法1:非同期呼び出し、統一回復結果

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
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__':
    pool = ProcessPoolExecutor()
    l1 = []
    for i in range(10):
        obj = pool.submit(task,i)
        l1.append(obj)
    pool.shutdown(wait = True)
    for i in l1:
        print(i.result())
    print('====主')
## 统一回收结果:我不能马上收到任何一个已经完成的任务的返回值,
# 我只能等到所有的任务全部结束后统一回收

第二の方法:

非同期コールバックコール+

爬虫

ブラウザがサーバに要求を送信する、働く、サーバが正しいならば、ブラウザはファイル、あなたが見る美しい外観にレンダリングファイルコードを受け取り、お使いのブラウザがファイルを返す与え、あなたの要求を検証します

何爬虫類?

  1. コードを使用してブラウザをシミュレートし、ブラウザは、ソースコードの束のためのワークフローを実行します
  2. データクレンジングのためのソースコードは、私が欲しいデータを取得します
import requests
ret = requests.get('http://www.baidu.com')
if ret.status_code == 200:
    print(ret.text)  #  得到源代码

バージョン1:

版本一:

     1. 异步发出10个任务,并发的执行,但是统一的接收所有的任务的返回值.(效率低,不能实时的获取结果)

     2. 分析结果流程是串行,影响效率.

          for res in obj_list:

             print(parse(res.result()))
             
             
       版本一:
         线程池设置4个线程, 异步发起10个任务,每个任务是通过网页获取源码, 并发执行,
         最后统一用列表回收10个任务, 串行着分析源码.(没有对数据进行操作)

コード分​​析

from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time
import random
import os
import requests
def task(url):
    ret = requests.get(url)
    if ret.status_code == 200:
        return ret.text

def parse(content):
    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()))

バージョン2

版本二:

        线程池设置4个线程, 异步发起10个任务,每个任务是通过网页获取源码+数据分析, 并发执行,

         最后将所有的结果展示出来.

         耦合性增强了.

         并发执行任务,此任务最好是IO阻塞,才能发挥最大的效果
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
import time
import random
import os
import requests
def task(url):
    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 = 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(res.result())
        
        
2381
100180
100180
100180
143902
47067
2708
21634
48110
571508   

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(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

おすすめ

転載: www.cnblogs.com/hualibokeyuan/p/11414125.html