Python之并发、并行、阻塞、非租塞、同步、异步、IO多路复用

一、并发并行

并发:表示执行多个任务的能力

并行:表示同一时刻执行多个任务

二、模拟socket发送http请求

三大步骤:创建连接 要发送的东西 然后数据回来接收    socket默认情况下阻塞

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3
 4 import socket
 5
 6 client = socket.socket()
 7 client.setblocking(False)  # 这里设置非阻塞
 8 # 百度创建连接:阻塞
 9 try:
10     client.connect((‘www.baidu.com‘, 80))  # 执行了但报错
11 except BlockingIOError as e:
12     pass
13
14 # 发送要东西了
15 client.sendall(b‘GET /s?wd=hello HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n‘)
16
17 # 百度给我的回复
18 chunk_list = []
19 while True:
20     try:
21         # 阻塞
22         chunk = client.recv(8096)
23         if not chunk:
24             break
25         chunk_list.append(chunk)
26     except BlockingIOError:
27         pass
28
29 print(b‘‘.join(chunk_list).decode(‘utf8‘))

三、基于单线程和IO多路复用发送多个任务(并发方法一非阻塞)

IO多路复用作用:只是检测socket的变化 是否连接成功 是否返回数据 是否可读可写

rlist, wlist, elist = select.select(socket_list, conn_list, [], 0.005)  

conn_list   检测其中所有socket对象是否与服务器连接成功   可写socket_list   检测服务器是否有数据给我返回来         可读[]    检测是否有错误    连接最大超出的时间为0.005秒rlist     返回数据的放在rlist中wlist     把连接成功的放在wlist列表中 

实现的方式有两种

select.select(socket_list, conn_list, [], 0.005)    select监听的socket_list, conn_list内部会调用列表中的每一个值得fileno方法,获取该返回值并去系统中检测    方式一:    select.select([client1, client2], [client1, client2], [], 0.005)    方式二:高级版本  封装socket对象    select.select([Foo(client1), Foo(client2)], [Foo(client1), Foo(client2)], [], 0.005)
 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3
 4 import socket
 5 import select
 6
 7 client1 = socket.socket()
 8 client1.setblocking(False)
 9 try:
10     client1.connect(("www.baidu.com", 80))
11 except BlockingIOError as e:
12     pass
13
14 client2 = socket.socket()
15 client2.setblocking(False)
16 try:
17     client2.connect(("www.so.com", 80))
18 except BlockingIOError as e:
19     pass
20 socket_list = [client1, client2]
21 conn_list = [client1, client2]
22 while True:
23     rlist, wlist, elist = select.select(socket_list, conn_list, [], 0.005)
24     for sk in wlist:
25         if sk == client1:
26             sk.sendall(b‘GET /s?wd=hello HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n‘)
27         else:
28             sk.sendall(b‘GET /s?q=hello HTTP/1.0\r\nhost:www.so.com\r\n\r\n‘)
29         conn_list.remove(sk)
30
31     for sk in rlist:
32         chunk_list = []
33         while True:
34             try:
35                 chunk = sk.recv(8096)
36                 if not chunk:
37                     break
38                 chunk_list.append(chunk)
39             except BlockingIOError as e:
40                 break
41         body = b"".join(chunk_list)
42         print("----->", body.decode(‘utf8‘))
43         # print("----->", body)
44         sk.close()
45         socket_list.remove(sk)
46     if not socket_list:
47         break
48
49 """
50 回调:异步本质(通知)
51 def callback(arg):
52     print(arg)
53 func("www.baidu.com/s?wd=hello" callback)
54 print(123)
55 print(123)
56 print(123)
57 """

四、利用单线程实现高并发NB高级版本(高并发方法二异步非阻塞)

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3
 4 import socket
 5 import select
 6
 7
 8 class Req(object):
 9     def __init__(self, sk, func):
10         self.sock = sk
11         self.func = func
12
13     def fileno(self):
14         return self.sock.fileno()
15
16
17 class Nb(object):
18
19     def __init__(self):
20         self.conn_list = []
21         self.socket_list = []
22
23     def add(self, url, func):
24         client = socket.socket()
25         client.setblocking(False)
26         try:
27             client.connect((url, 80))
28         except BlockingIOError as e:
29             pass
30         obj = Req(client, func)
31         self.conn_list.append(obj)
32         self.socket_list.append(obj)
33
34     def run(self):
35         while True:
36             rlist, wlist, elist = select.select(self.socket_list, self.conn_list, [], 0.005)
37             for sk in wlist:
38                 sk.sock.sendall(b‘GET /s?wd=hello HTTP/1.0\r\nhost:www.baidu.com\r\n\r\n‘)
39                 self.conn_list.remove(sk)
40
41             for sk in rlist:
42                 chunk_list = []
43                 while True:
44                     try:
45                         chunk = sk.sock.recv(8096)
46                         if not chunk:
47                             break
48                         chunk_list.append(chunk)
49                     except BlockingIOError as e:
50                         break
51                 body = b"".join(chunk_list)
52                 sk.func(body)
53                 sk.sock.close()
54                 self.socket_list.remove(sk)
55             if not self.socket_list:
56                 break
57
58
59 def baidu_response(body):
60     print(‘百度下载的结果‘, body)
61
62
63 def sogou_response(body):
64     print(‘搜狗下载的结果‘, body)
65
66
67 t1 = Nb()
68 t1.add(‘www.baidu.com‘, baidu_response)
69 t1.add(‘www.so.com‘, sogou_response)
70 t1.run()

总结:

IO多路复用的作用: 检测多个socket是否发生变化            操作系统检测socket是否发生变化 有三种模式            select:最多1024个socket个数  循环去检测。            poll:  不限制监听socket个数,循环去检测。(水平触发)            epoll: 不限制监听socket个数,回调的方式(边缘触发)  windows下没有  触发的机制可以采用简单点儿的高低电平来理解     linux下select.epoll  有点复杂注册哪些等等操作  用法差不多select.select
            提高并发方案:多进程 多线程 异步非阻塞模块(Twisted)            什么是异步非阻塞?    非阻塞, 不等待 比如:创建socket对某个地址进行连接,获取接收数据时就会等待,连接成功/接收到数据时,            才执行后续操作,如果设置setblocking(False),上边两过程不再等待,但是要报错BlockingError,只要去捕获即可            异步:(通知)执行完成之后自动执行回调函数或者自动执行某些操作(通知)最根本就是执行完某个任务自动调用我给他的函数                比如:爬虫中向某个地址发送请求,当请求执行完成之后自动执行回调函数

            什么是同步阻塞?            同步:按照顺序逐步执行            阻塞:等待

    这么多代码其实可以不用写 基于异步非阻塞的框架 基于事件循环(驱动) Twisted

 

原文地址:https://www.cnblogs.com/Alexephor/p/11229111.html

时间: 2024-08-15 03:30:44

Python之并发、并行、阻塞、非租塞、同步、异步、IO多路复用的相关文章

C# 【一】进程 , 线程 , 微线程 , 同步 , 异步 , 并发 , 并行 , 阻塞 , 非阻塞

一 理解篇 前言 本文仅仅用作借鉴使用,作者刚入行不久,所以请不小心看到这篇文章的朋友,手下留情. 本文以小故事的形式进行叙述,逻辑不通之处.请理解. 如有错误 ,欢迎指出. 谢谢.                                                           最后修改时间:2019-01-25 1.0.0 进程 老刘是一个软件公司的老板,公司下有两个部门,产品设计部门(产品进程)和研发部门(研发进程),产品设计部门在一楼,研发部门在二楼(独立地址空间).

# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # Select\Poll\Epoll异步IO 以及selectors模块 # Python队列/RabbitMQ队列

1 # 进程/线程/协程 2 # IO:同步/异步/阻塞/非阻塞 3 # greenlet gevent 4 # 事件驱动与异步IO 5 # Select\Poll\Epoll异步IO 以及selectors模块 6 # Python队列/RabbitMQ队列 7 8 ############################################################################################## 9 1.什么是进程?进程和程序之间有什么

python开发IO模型:阻塞&非阻塞&异步IO&多路复用&selectors

一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西.这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同.所以,

Python番外之 阻塞非阻塞,同步与异步,i/o模型

1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步:      所谓同步,就是在c端发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:      异步的概念和同步相对.当c端一个异步过程调用发出后,调

基础入门_Python-网络编程.分分钟掌握阻塞/非阻塞/同步/异步IO模型?

概念梳理: 故事独白: 满满爱喝茶,废话不多说,开始煮开水. 出场人物: 满满, 普通水壶, 高级水壶(水开会响) 1. 满满把水壶放在火上, 站在那里等水开(同步阻塞) 满满觉得自己有点儿傻逼~ 2. 满满把水壶放在火上,去客厅看电视,时不时的去厨房瞅瞅水开木有(同步非阻塞) 满满觉得自己还是有点傻~,于是买了个高级水壶, 水开后会响~ 3. 满满把高级水壶放在火上, 站在那里等水开(异步阻塞) 满满想高级水壶水开会自己叫~为毛不去看个电视哪? 4. 满满把高级水壶放在火上, 去客厅看电视,

Java 中阻塞非阻塞io以及同步异步IO

然后借鉴下<Unix网络编程卷>中的理论: IO操作中涉及的2个主要对象为程序进程.系统内核.以读操作为例,当一个IO读操作发生时,通常经历两个步骤: 1,等待数据准备 2,将数据从系统内核拷贝到操作进程中 例如,在socket上的读操作,步骤1会等到网络数据包到达,到达后会拷贝到系统内核的缓冲区:步骤2会将数据包从内核缓冲区拷贝到程序进程的缓冲区中. 阻塞(blocking)与非阻塞(non-blocking)IO IO的阻塞.非阻塞主要表现在一个IO操作过程中,如果有些操作很慢,比如读操作

使用ab.exe监测100个并发/100次请求情况下同步/异步访问数据库的性能差异

ab.exe介绍 ab.exe是apache server的一个组件,用于监测并发请求,并显示监测数据 具体使用及下载地址请参考:http://www.cnblogs.com/gossip/p/4398784.html 本文的目的 通过webapi接口模拟100个并发请求下,同步和异步访问数据库的性能差异 创建数据库及数据 --创建表结构 CREATE TABLE dbo.[Cars] ( Id INT IDENTITY(1000,1) NOT NULL, Model NVARCHAR(50) 

Python的并发并行[3] -&gt; 进程 -&gt; subprocess 模块

subprocess 模块 0 模块描述 / Module Description From subprocess module: """Subprocesses with accessible I/O streams This module allows you to spawn processes, connect to their input/output/error pipes, and obtain their return codes. For a complet

Python的并发并行[2] -&gt; 队列 -&gt; queue 模块

queue 模块 / queue Module 1 常量 / Constants Pass 2 函数 / Function Pass 3 类 / Class 3.1 Queue类 类实例化:queue = queue.Queue(maxsize=0) 类的功能:用于生成一个先入先出队列实例 传入参数: maxsize maxsize: int类型,队列的最大值,无空间时阻塞,未指定时为无限队列 返回参数: queue queue: instance类型,生成的先入先出队列实例 3.1.1 put