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

进程、线程分别用到的模块是 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)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值