事件驱动模型与IO模型

事件驱动模型

事件驱动模型与IO模型

 

 

 

事件驱动编程,是一种编程范式。这里程序的执行流由外部事件来决定。它的特点是包含一个循环,当外部事件发生时,使用回调机制来触发相应的处理。

另外2种常见的编程范式是(单线程)同步以及多线程编程

 

 

IO模型

 

事件驱动模型与IO模型

 

 事件驱动模型与IO模型

 

 同步IO(synchronous),异步IO(asynchronous),阻塞IO(blocking) 和非阻塞IO(non-blocking) 都是独立的,不一起出现

5种IO模型如下:

-blocking IO 

-nonblocking IO

-IO multiplexing(IO多路复用)

-signal driven IO

-asynchronous IO

 

blocking IO (阻塞IO)

在linux 中,默认情况下所有的socket 都是blocking IO,阻塞IO 只发生了一次系统调用

事件驱动模型与IO模型

 

 实例:

-server 端

import socket

sk=socket.socket()

sk.bind(("127.0.0.1",8080))

sk.listen(5)

while 1:
conn,addr=sk.accept()

while 1:
conn.send("hello client".encode("utf8"))
data=conn.recv(1024)
print(data.decode("utf8"))

-client端

import socket

sk=socket.socket()

sk.connect(("127.0.0.1",8080))

while 1:
data=sk.recv(1024)
print(data.decode("utf8"))
sk.send(b"hello server")

 

非阻塞IO

 

缺点:不能及时收发消息,系统调用太多次

事件驱动模型与IO模型

 

 实例

-server 端

import time
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.bind((‘127.0.0.1‘,6667))
sk.listen(5)
sk.setblocking(False) #此代码代表不会一值等待连接(如上图)
print (‘waiting client connection .......‘)
while True:
try:

connection,address = sk.accept() # 进程主动轮询
print("+++",address)
client_messge = connection.recv(1024)
print(str(client_messge,‘utf8‘))
connection.close()
except Exception as e:
print (e)
time.sleep(4)

-client 端

import time
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

while True:
sk.connect((‘127.0.0.1‘,6667))
print("hello")
sk.sendall(bytes("hello","utf8"))
time.sleep(2)
break

 

IO multiplexing(IO多路复用)

 

事件驱动模型与IO模型

 

 

IO多路复用实现并发的方法:

1)select  可跨平台使用,但是监听连接数最大为1024

2)  poll     

3) epoll (推荐使用):效率高,最好的实现方式

 实例一:

-server 端

import socket
import select
sk=socket.socket()
sk.bind(("127.0.0.1",9904))
sk.listen(5)
inp=[sk,]
while True:

r,w,e=select.select(inp,[],[],5) #[sk,conn]
#inp是指输入内容,第一个[]是输出,第二个[]是报错,数字5是每隔5秒监听一次(可自己设置秒数)


for i in r:#[sk,]
conn,add=i.accept()
print(conn)
print("hello")
inp.append(conn)
print(‘>>>>>>‘)

-client 端

import socket

sk=socket.socket()

sk.connect(("127.0.0.1",9904))

while 1:
inp=input(">>").strip()
sk.send(inp.encode("utf8"))
data=sk.recv(1024)
print(data.decode("utf8"))

 

事件驱动模型与IO模型

 

 select 是水平触发

 

实例二:

server 端

import socket
import select
sk=socket.socket()
sk.bind(("127.0.0.1",8801))
sk.listen(5)
inputs=[sk,]
while True:
r,w,e=select.select(inputs,[],[],5)

for obj in r:#[sk,]
if obj==sk:
conn,add=obj.accept()
print(conn)
inputs.append(conn)
else:
data_byte=obj.recv(1024)
print(str(data_byte,‘utf8‘))
inp=input(‘回答%s号客户>>>‘%inputs.index(obj))
obj.sendall(bytes(inp,‘utf8‘))

print(‘>>‘,r)

client 端

import socket

sk = socket.socket()
sk.connect((‘127.0.0.1‘, 8801))

while True:
inp = input(">>>>")
sk.sendall(bytes(inp, "utf8"))
data = sk.recv(1024)
print(str(data, ‘utf8‘))

 

异步IO(asynchronous IO)

 

异步IO:全程无阻塞

事件驱动模型与IO模型

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

事件驱动模型与IO模型

上一篇:震源机制解、走滑类型


下一篇:Qt 框架应用程序下使用jpg图片时不显示现象