并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io

1.io模型提交任务得方式:    同步:提交完任务,等结果,执行下一个任务    异步:提交完,接着执行,异步 + 回调  异步不等结果,提交完任务,任务执行完后,会自动触发回调函数同步不等于阻塞:    阻塞:遇到io,自己不处理,os会抢走cpu ,解决办法:监测到io,gevent切换到其他任务,类似欺骗os    非阻塞:cpu 运行
IO分类:    1.阻塞IO        blocking IO    2.非阻塞IO      nonblocking IO    3.IO多路复用    IO multiplexing    4.信号驱动IO    signal driven IO     用得比较少     5.异步IO        asynchronous IO
遇到IO: 卡    网络IO: 原地阻塞    1.server端什么样得操作属于IO行为             # accept recv send 阻塞操作   accept recv 明显得等  send 不会明显等,但是一种io行为      2.为什么IO行为会让有在原地等待的效果  

2.阻塞ioserver:
 1 from socket import *
 2 from threading import Thread
 3
 4 def communicate(conn):
 5     while True:
 6         try:
 7             data = conn.recv(1024)
 8             if not data: break
 9             conn.send(data.upper())
10         except ConnectionResetError:
11             break
12
13     conn.close()
14
15
16
17 server = socket(AF_INET, SOCK_STREAM)
18 server.bind((‘127.0.0.1‘,8080))
19 server.listen(5)
20
21 while True:
22     print(‘starting...‘)
23     conn, addr = server.accept()  # io 阻塞 os拿走了cpu
24     print(addr)
25
26     t=Thread(target=communicate,args=(conn,))
27     t.start()
28
29 server.close()
client:
 1 from socket import *
 2
 3 client=socket(AF_INET,SOCK_STREAM)
 4 client.connect((‘127.0.0.1‘,8080))
 5
 6
 7 while True:
 8     msg=input(‘>>: ‘).strip()
 9     if not msg:continue
10     client.send(msg.encode(‘utf-8‘))
11     data=client.recv(1024)
12     print(data.decode(‘utf-8‘))
13
14 client.close()
3.非阻塞io:自己监测io 遇到io 就切 并且把 单线程得效率提到最高导致得问题:    1.当有数据来得时候,cpu 在做其他得事情,不会立即响应    2.服务端没有任何阻塞,说白了,就是死循环,cpu会一直运转,线程处于就绪状态,大量占用cpu ,做无用,这个线程会一直问cpu,有数据没,有数据没不推荐使用server:
 1 from socket import *
 2
 3 server = socket(AF_INET, SOCK_STREAM)
 4 server.bind((‘127.0.0.1‘,8083))
 5 server.listen(5)
 6 server.setblocking(False)   # 默认True 阻塞
 7 print(‘starting...‘)
 8
 9
10 rlist=[]
11 wlist=[]
12 while True:
13
14     try:  # 服务端不停得建链接
15         conn, addr = server.accept()
16         rlist.append(conn)
17         print(rlist)
18     except BlockingIOError:  # 没阻塞
19         # print(‘干其他的活‘)
20
21         #收消息
22         del_rlist = []
23         for conn in rlist:
24             try:
25                 data=conn.recv(1024)
26                 if not data:
27                     del_rlist.append(conn)
28                     continue
29                 wlist.append((conn,data.upper()))
30             except BlockingIOError:
31                 continue
32             except Exception:
33                 conn.close()
34                 del_rlist.append(conn)
35
36         #发消息
37         del_wlist=[]
38         for item in wlist:
39             try:
40                 conn=item[0]
41                 data=item[1]
42                 conn.send(data)  # send 在数据量 过大时 也会阻塞
43                 del_wlist.append(item)
44             except BlockingIOError:
45                 pass
46
47         for item in del_wlist:
48             wlist.remove(item)
49
50         for conn in del_rlist:
51             rlist.remove(conn)
52
53
54 server.close()
client:
 1 from socket import *
 2
 3 client=socket(AF_INET,SOCK_STREAM)
 4 client.connect((‘127.0.0.1‘,8083))
 5
 6
 7 while True:
 8     msg=input(‘>>: ‘).strip()
 9     if not msg:continue
10     client.send(msg.encode(‘utf-8‘))
11     data=client.recv(1024)
12     print(data.decode(‘utf-8‘))
13
14 client.close()
4.多路复用io:    wait copy  还多了select  中间有个中介存在,帮问os 有没有数据    但是如果中介 只有1个 效率不如 阻塞效率    但是如果中介监测多个套接字 ,性能高就是:同时监测多个套接字问os系统好了没  就比阻塞io效率高     监测套接字得io行为    服务端得套接字有几类:server conn

select 阻塞io 效率高       比非阻塞io 效率也高 ,一直做无用

总结:   同时监测多个套接字   列表 循环 慢 假设列表数据多,循环 效率低  监测套接字好没好 从头到尾 循环1遍   select  列表循环  效率低   poll   可接收得列表数据多 效率也不高   epoll 效率最高得 异步操作 每个套接字身上绑定个回调函数,谁好了谁触发回调,(就不用去遍历了 效率低)   epoll  windows 不支持          linux 支持   selectors 模块  自动根据操作系统选择   poll   epollserver:
 1 from socket import *
 2 import select
 3
 4 server = socket(AF_INET, SOCK_STREAM)
 5 server.bind((‘127.0.0.1‘,8083))
 6 server.listen(5)
 7 server.setblocking(False)
 8 print(‘starting...‘)
 9
10 rlist=[server,]
11 wlist=[]
12 wdata={}
13
14 while True:
15     rl,wl,xl=select.select(rlist,wlist,[],0.5) # [] 异常列表 每隔0.5s 问一次
16     print(‘rl‘,rl)
17     print(‘wl‘,wl)
18
19     for sock in rl:
20         if sock == server:
21             conn,addr=sock.accept()
22             rlist.append(conn)
23         else:
24             try:
25                 data=sock.recv(1024)
26                 if not data:
27                     sock.close()
28                     rlist.remove(sock)
29                     continue
30                 wlist.append(sock)
31                 wdata[sock]=data.upper()
32             except Exception:
33                 sock.close()
34                 rlist.remove(sock)
35
36     for sock in wl:
37         data=wdata[sock]
38         sock.send(data)
39         wlist.remove(sock)
40         wdata.pop(sock)
41
42 server.close()
client:
 1 from socket import *
 2
 3 client=socket(AF_INET,SOCK_STREAM)
 4 client.connect((‘127.0.0.1‘,8083))
 5
 6
 7 while True:
 8     msg=input(‘>>: ‘).strip()
 9     if not msg:continue
10     client.send(msg.encode(‘utf-8‘))
11     data=client.recv(1024)
12     print(data.decode(‘utf-8‘))
13
14 client.close()



原文地址:https://www.cnblogs.com/alice-bj/p/8722799.html

时间: 2024-10-12 16:11:22

并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io的相关文章

《Java并发编程实战》第十五章 原子变量与非阻塞同步机制 读书笔记

一.锁的劣势 锁定后如果未释放,再次请求锁时会造成阻塞,多线程调度通常遇到阻塞会进行上下文切换,造成更多的开销. 在挂起与恢复线程等过程中存在着很大的开销,并且通常存在着较长时间的中断. 锁可能导致优先级反转,即使较高优先级的线程可以抢先执行,但仍然需要等待锁被释放,从而导致它的优先级会降至低优先级线程的级别. 二.硬件对并发的支持 处理器填写了一些特殊指令,例如:比较并交换.关联加载/条件存储. 1 比较并交换 CAS的含义是:"我认为V的值应该为A,如果是,那么将V的值更新为B,否则不需要修

JAVA并发编程2_线程安全&内存模型

"你永远都不知道一个线程何时在运行!" 在上一篇博客JAVA并发编程1_多线程的实现方式中后面看到多线程中程序运行结果往往不确定,和我们预期结果不一致.这就是线程的不安全.线程的安全性是非常复杂的,没有任何同步的情况下,多线程的执行顺序是不可预测的.当多个线程访问同一个资源时就会出现线程安全问题.例如有一个银行账户,一个线程往里面打钱,一个线程取钱,要是得到不确定的结果那是多么可怕的事情. 引入: 例如下面的程序,在单线程下,执行两次i++理论上i的最终值是12,但是在多线程环境下则不

(更新中)谈谈个人对java并发编程中(管程模型,死锁,线程生命周期等问题) 见解

之前未曾接触过多线程编程  公司的项目开始用到多线程,所以自己谈谈个人对于并发编程的见解. 并发编程会导致线程不安全,常说的线程不安全指的是  多个线程操作一个共享数据,导致线程之间的读取到的数据不一致. 并发编程导致线程不安全的根源   可见性  原子性    有序性 1 .可见性     cpu缓存导致. 一般cpu缓存中进行操作之后再将数据写到内存,在多核服务器中  每个线程都会分配一个cpu  都会在各自的cpu中进行处理再将数据统一写到内存中.每个cpu缓存中的数据都是不可见的.导致最

什么是阻塞式和非阻塞io流?

阻塞IO:socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回. 非阻塞IO:非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功. 两者区别: 所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止. 对于非阻塞状态, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待 . 一种常用做法是:每建立一个Socket连接时,同时创建一个新线程对

并行,并发,串行,同步,异步,阻塞,非阻塞,同步阻塞,同步非阻塞,异步阻塞,异步非阻塞

并行和并发 并发和并行从宏观上来讲都是同时处理多路请求的概念.但并发和并行又有区别,并行是指两个或者多个事件(多核线程)在同一时刻发生:而并发是指两个或多个事件(进程或者程序)在同一时间间隔内发生.计算机在宏观上并发,微观上并行. 在操作系统中,并发是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行. ①程序与计算不再一一对应,一个程序副本可以有多个计算 ②并发程序之间有相互制约关系,直接制约体现为一个程序需

Akka并发编程——第八节:Actor模型(七)

本节主要内容 停止运行Typed Actor 当Typed Actor不再需要时要将其停止,有3种方法停止Typed Actor的运行: (1)通过system.shutdown()停止ActorSystem中所有的Typed Actor: (2)调用TypedActor(system).stop(mySquarer)停止指定的Typed Actor: (3)调用TypedActor(system).poisonPill(otherSquarer)停止指定的Typed Actor. 具体使用代码

UNIX网络编程-非阻塞connect和非阻塞accept

1.非阻塞connect 在看了很多资料之后,我自己的理解是:在socket发起一次连接的时候,这个过程需要一段时间来将三次握手的过程走完,如果在网络状况不好或者是其他的一些情况下,这个过程需要比较长的时间,我们在连接之前将socket设置为非阻塞模式之后,调用connect函数之后,立即返回,如果成功返回0,如果不成功则返回EINPROGRESS,这个值表明连接正在进行,我们可以设置一个超时时间,然后在这个时间段内不停的检查socket是否连接上了,如果在这个时间段内还没有连上,则返回失败.在

服务器编程心得(四)—— 如何将socket设置为非阻塞模式

1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ int type, _In_ int protocol ); SOCKET WSASocket( _In_ int af, _In_ int type, _In_ int protocol, _In_ LPWSAPROTOCOL_INFO lpProtocolInfo, _In_ GROUP g,

并发编程实践四:实现正确和高效的锁

你是否觉得锁是一种很神奇的东西,在并发编程中,你只需要将你的代码加上锁,就能保证代码是线程安全的(当然现实和感觉有很大差别,代码的线程安全是非常复杂的),那么,这些都是怎么做到的呢?当存在大量线程同时竞争锁时,竞争失败的锁会怎么做呢?锁又是怎么保证这一切高效的执行的呢?这篇文章将为你回答这些问题,首先我将介绍怎样实现一个正确的锁,然后介绍高效的锁应该具备的条件,最后将介绍两种常用的队列锁算法:CLH锁和MCS锁. 文中将用到一些原子变量的特性,你可以将原子变量看作加强版的volatile变量,具

python并发编程&IO模型

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