您的位置:首页 > 编程语言 > Python开发

Python 中进程、线程、协程、IO复用

2017-05-01 23:32 441 查看
进程、线程分别用到的模块是 multiprocessing.Process 和 threading.Thread

方法有 start() join() 等

同时在线程和进程中都可以调用 Queue(主要用put,get) 和Lock(acquire、release)。在进程中虽然各自拥有独立的内存,但是为了防止同时使用输出(CMD,还有桌面??不太确定),还是有机会用到Lock。

另外就是携程! 它其实就是线程的小弟、运行的时候是一个线程假装并发执行多个函数(就像通过yield 分批次执行)

大概就是这个赶脚:

def run(n):
for i in range(n):
print 'running %d'%i
yield i

def work(n):
for i in range(n):
print 'working %d'%i
yield i

r=run(10)
w=work(10)
for i in range(10):
r.next()
w.next()
print i


这种协程可以用 greenlet 来操作,利用其switch() 函数,互相切换(手工)

另外还可以自动切换,根据什么切换呢?? 根据IO,一旦要用到IO则先调用系统IO操作的接口,然后该线程继续往下执行,当系统操作完IO,将数据送到用户内存空间的时候,线程又滚回来操作。【PS: 据说这种用得比较少,因为复杂,还有系统哪里好像也不怎么支持。PPSS:大神说的】

IO操作分为:阻塞,非阻塞,IO多路复用,异步IO

第1,2没什么好说的,第4种就是刚刚上面说的自动切换。

主要说说第三种:

select:

监听N个IO,一旦有情况,系统就会通知,但不告诉你哪个IO有信息

该段代码应该只有python 3以上才能运行,因为2.7的server 和 3.0的server返回的值不一样

#encoding:utf-8
import socket
import select
host = '127.0.0.1'
port = 12345
server = socket.socket()
server.bind((host,port))
server.listen(50)
server.setblocking(False)
inputs = [server,]   #监测列表,一开始先监测自己
outputs = []
while 1:
readable,writeable,exceptional = select.select(inputs,outputs,inputs)#读,写,异常监测(监测读列表的异常)
conn = None
addr = None
for r in readable:
if r is server: #如果返回的连接是server,代表来了一个新链接
conn,addr = server.accept()
inputs.append(conn)  #将连接进服务器的连接加入监听列表
else:
#conn,addr = server.accept() ,这个当然是错的,应该接收最新发送数据的连接
conn,addr = r.accept()
print conn.recv(1024)   #如果监听到除了server以外的连接,则说明该次传输的时数据


poll

select默认只能监听1024,但它没限制,其他同上。

epoll

可以知道是哪个IO有信息

selector 模块:默认使用epoll 如果是windows 则用select

import selectors
def accept(conn,mask):#server 收到新链接的回调函数
new_conn = server.accept()
new_conn.setblocking(False)
sel.register(server,selectors.EVENT_READ,read)
#新链接则
def read(conn,mask):#当监听链接发送时的回调函数
data = conn.recv(1024)
if data:
print(data)
else:
sel.unregister(conn)
#如果没收到数据,表明链接断了,则注销该监听
print("nothing")

server.bind((host,port))
server.listen(50)
server.setblocking(False)
sel = selectors.DefaultSelector()
sel.register(server,selectors.EVENT_READ,accept)
#accept 会在监听到有连接的时候执行
while True:
event = sel.select() #名字是select但有可能是epoll
#默认是阻塞,返回活动连接列表
for key ,mask in event:
callback = key.data
callback(key.fileobj,mask)
#key.fileobj 是文件句柄(相当于上面代码中还没有建立链接的r)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python 线程