python基础学习23----IO模型(简)

python基础学习23----IO模型(简),第1张

概述对于一个网络IO(network IO),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read *** 作发生时,该 *** 作会经历

对于一个网络IO(network IO),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read *** 作发生时,该 *** 作会经历两个阶段:

1.等待数据准备

2.将数据从系统内核拷贝到进程当中

当收到数据后,这些数据会先存放到系统所用的内存当中,之后在由系统将数据从内核中拷贝到使用的进程当中

不同的IO模型的区别就在于上述的两个阶段

recvfrom进行系统调用后,等待数据和拷贝数据的两个阶段都被阻塞了

recvfrom不断的向kernel要数据,如果没有数据就马上返回一个提示,紧接着recvfrom继续去要数据,直到数据准备好, 然后再从内核拷贝到进程中。

这里等待数据的阶段并没有阻塞,但是数据从内核中拷贝到使用的进程的过程中还是处于阻塞状态。

缺点:循环调用recv()将大幅度推高cpu占用率,任务完成的响应延迟增大了,因为每过一段时间才去轮询一次read *** 作,而任务可能在两次轮询之间的任意时间完成。这会导致整体数据吞吐量的降低。

当用户进程调用了select,那么整个进程会被block,而同时,kernel会“监视”所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用read *** 作,将数据从kernel拷贝到用户进程。

这里两个阶段都处于阻塞状态,看似和阻塞IO没有太大区别,甚至比它效率更低,但是select能够处理多个连接。

s@H_403_12@=<span >socket(AF_INET,SOCK_STREAM)
s.setsockopt(Sol_SOCKET,SOREUSEADDR,@H403_12@1<span >)
s.bind((@H_403_12@<span >'@H_403_12@<span >127.0.0.1@H_403_12@<span >'@H_403_12@,8081<span >))
s.Listen(@H_403_12@5<span >)
s.setblocking(False)
readl@H403_12@=<span >[s,]
@H_403_12@<span >while@H_403_12@<span > True:
r_l,w_l,xl@H403_12@=<span >select.select(readl,[],[])
@H
403_12@<span >print@H_403_12@<span >(rl)
@H
403_12@<span >for@H_403_12@ ready_obj <span >in@H_403_12@<span > rl:
@H
403_12@<span >if@H_403_12@ ready_obj ==<span > s:
conn,addr@H_403_12@=<span >ready_obj.accept()
readl.append(conn)
@H
403_12@<span >else@H_403_12@<span >:
@H_403_12@<span >try@H_403_12@<span >:
data@H_403_12@=ready_obj.recv(1024<span >)
@H_403_12@<span >if@H_403_12@ <span >not@H_403_12@<span > data:
read_l.remove(readyobj)
@H
403_12@<span >continue@H_403_12@<span >
readyobj.send(data.upper())
@H
403_12@<span >except@H_403_12@<span > ConnectionresetError:
read_l.remove(readyobj)@H403_12@

@H_403_12@<span >while@H_403_12@<span > True:
msg@H_403_12@=input(<span >'@H_40312@<span >>>: @H403_12@<span >'@H_403_12@<span >)
@H_403_12@<span >if@H_403_12@ <span >not@H_403_12@ msg:<span >continue@H_403_12@<span >
c.send(msg.encode(@H_403_12@<span >'@H_403_12@<span >utf-8@H_403_12@<span >'@H_403_12@<span >))
data@H_403_12@=c.recv(1024<span >)
@H_403_12@<span >print@H_403_12@(data.decode(<span >'@H_403_12@<span >utf-8@H_403_12@<span >'@H_403_12@))

异步IO两个阶段都没有阻塞

用户进程发起read *** 作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read *** 作完成了。

具体参考href="https://www.cnblogs.com/haiyan123/p/7465486.HTML" target="_blank">https://www.cnblogs.com/haiyan123/p/7465486.HTML

总结

以上是内存溢出为你收集整理的python基础学习23----IO模型(简)全部内容,希望文章能够帮你解决python基础学习23----IO模型(简)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1208203.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存