http://www.cnblogs.com/yuanchenqi/articles/6755717.html
selector模块
@程序运行流程 1,建议大家用selectors模块,此模块IO多路复用会自动选择最佳模型 2,在客户端第一次连接的时候,完成一次注册sel.register(sock,selectors.EVENT_READ,accept),其中注册只是放到列表中 一旦有变化(sock)就会触发accept函数, # print(key.fileobj) #第一次时sock # print(key.data) #第一次时 accept accept函数完成对conn的注册,加入到注册表中监控起来,sel.register(conn,selectors.EVENT_READ,read) 开始通信时,sock不变, # print(key.fileobj) # 通信时 conn # print(key.data) # 通信时 read 然后read调用conn,如果客户端在win下突然断掉还会报错,所以就try,把注册去掉就行了,linux也是 3,用的时候都不用动,只要写accept函数,和read函数及可 import selectors # 基于select模块实现的IO多路复用,建议大家使用 import socket sock=socket.socket() sock.bind(("127.0.0.1",8800)) sock.listen(5) sock.setblocking(False) sel=selectors.DefaultSelector() #根据具体平台选择最佳IO多路机制,比如在linux,选择epoll def read(conn,mask): try: data=conn.recv(1024) print(data.decode("UTF8")) data2=input(">>>") conn.send(data2.encode("utf8")) except Exception: sel.unregister(conn) def accept(sock,mask): conn, addr = sock.accept() print("conn",conn) sel.register(conn,selectors.EVENT_READ,read) #监听谁就把谁写到注册函数里,read是自己写的, conn sel.register(sock,selectors.EVENT_READ,accept) # 注册事件,不是监听 不会卡到那,只是把sock,appcet绑定到这个对像去了, #sock有变化直接触发accept,中间的参数没用 while 1: print("wating...") events=sel.select() # 监听,会卡到那 [(key1,mask1),(key2,mask2)],mask没有用,每注册一个都会以元组形式加到这里面, for key,mask in events: # print(key.fileobj) #第一次时sock # 通信时 conn # print(key.data) #第一次时 accept # 通信时 read func=key.data obj=key.fileobj func(obj,mask) # 1次 accept(sock,mask) # 2次 read(conn,mask) IO多路复用实现机制 win: 下只有select linux: 下有select, poll, epoll select就是反复的遍历,而epoll是绑定回调函数,实现信号触发,不再遍历 select是效率最低的 只有一个函数 1,每次调用select都需要将所有的 fd(文件描述符)从用户空间cp到内核空间,导致效率下降 2,遍历所有的fd是否有数据访问,最重要的问题cpu数的时间多 3,最大连接数1024 poll跟select完全一样,只是在最大连接数做了个改进,没有限制了,只有一个函数 epoll:通过三个函数来实现 1 第一个函数来创建一个epoll句柄,fd(文件描述符)从用户空间cp到内核空间,只拷一次 2,回调函数,某一个函数或者某一个动作成功完成后会触发的函数 为所有的fd绑定一个回调函数,一旦有数据访问,触发回调函数 回调函数将fd放到链表中 3,连接数不限(端口,什么的也没那嘛多)
队列
import queue #q=queue.Queue(3) # 默认是 先进先出(FIFO) # q.put(111) # q.put("hello") # q.put(222) # # q.put(223,False) # # print(q.get()) # # print(q.get()) # # print(q.get()) # # # q.get(False) # queue 优点: 线程安全的 我不想用锁来控制,就想用queue来控制 # join和task_done # q=queue.Queue(5) # q.put(111) # q.put(222) # q.put(22222) # # # while not q.empty(): # a=q.get() # print(a) #q.task_done() # b=q.get() # print(b) # q.task_done() # q.join() # # print("ending") # 先进后出模式 # q=queue.LifoQueue() # Lifo last in first out # # # q.put(111) # q.put(222) # q.put(333) # # print(q.get()) # 优先级 # q=queue.PriorityQueue() # # q.put([4,"hello4"]) # q.put([1,"hello"]) # q.put([2,"hello2"]) # # print(q.get()) # print(q.get()) # import queue # # # q=queue.Queue() # # q.put(111) # q.put(2222) # q.put(22333) # # print( ) #生产者消费者模型 import time,random import queue,threading q = queue.Queue() def Producer(name): count = 0 while count <10: print("making........") time.sleep(2) q.put(count) print('Producer %s has produced %s baozi..' %(name, count)) count +=1 #q.task_done() #q.join() print("ok......") def Consumer(name): count = 0 while count <10: time.sleep(1) if not q.empty(): data = q.get() #q.task_done() #q.join() print(data) print('