Day10 IO多路复用,多线程,笔记

IO多路复用,多线程,笔记

一、笔记

笔记之lambda

li = [lambda:x for x in range(10)]
li 中的元素是什么?
li[0]()的结果是什么?

第一问:li 中的元素是10个相同功能的函数
第二问:li 循环第10次的时候x =9 ,所以li[0]()的结果是 9

笔记之Py27,Py35多继承

Python 27中:

经典类:

class A():
var = 'a'

def func(self):
print self.var

class B(A):
def f(self):
pass

class C(A):
var = 'c'

def func(self):
print self.var

class D(B,C):
def f(self):
pass

obj = D()
obj.func()

输出结果: a
寻找路径: D-->B-->A 经典类:深度优先遍历

新式类:

class A(object): # 注意新式类此处差异
var = 'a'

def func(self):
print self.var

class B(A):
def f(self):
pass

class C(A):
var = 'c'

def func(self):
print self.var

class D(B,C):
def f(self):
pass

obj = D()
obj.func()

输出结果: c
寻找路径: D-->B-->C--A 新式类:广度优先遍历

Py35 默认就是广度优先遍历方式

笔记之Python作用域

python中代码无块及作用域。Ptyon以函数为作用域

name = 'alex'

def f1():
print(name)

def f2():
name = 'eric'
f1()

f2()

输出结果:alex

为什么不是 eric?
python的作用域在执行之前已经确定!

Python作用域链,由内向外找,直到找不到报错!

name = 'alex'
def f1():
# name = 'a'
def f2():
# name = 'b'
print(name)
f2()
f1()

输出结果: alex
反注释 # name = 'b' 输出结果: b
反注释 # name = 'a' 输出结果: a

二、IO多路复用

与多线程和多进程相比,I/O多路复用的最大优势是系统开销小,系统不需要建立新的进程或者线程,也不必维护这些线程和进程。
主要应用:

  1. 客户程序需要同时处理交互式的输入和服务器之间的网络连接
  2. 客户端需要对多个网络连接作出反应
  3. TCP服务器需要同时处理多个处于监听状态和多个连接状态的套接字
  4. 服务器需要处理多个网络协议的套接字
  5. 服务器需要同时处理不同的网络服务和协议

elect,poll,epoll都是IO多路复用的机制。所谓I/O多路复用机制,就是说通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。select能够监视的描述符有限制,最多1024,而poll可以突破该限制,epoll则是增强的机制,不再主动监视,而是被监视的描述符自己有变化主动回调。以select为例:

socket server:

import socket
import select

sk = socket.socket()
sk.bind(('127.0.0.1', 9999,))
sk.listen(5)

inputs = [sk,]
outputs = []
messages = {}

while True:
rlist,wlist,elist, = select.select(inputs, outputs,[sk,],1)
print(len(inputs),len(rlist),len(wlist), len(outputs))
# 监听sk(服务器端)对象,如果sk对象发生变化,表示有客户端来连接了,此时rlist值为【sk】
# 监听conn对象,如果conn发生变化,表示客户端有新消息发送过来了,此时rlist的之为 【客户端】
for r in rlist:
if r == sk:
# 新客户来连接
conn, address = r.accept()
# conn是什么?其实socket对象
inputs.append(conn)
messages[conn] = []
conn.sendall(bytes('hello', encoding='utf-8'))
else:
# 有人给我发消息了
print('=======')
try:
ret = r.recv(1024)
if not ret:
raise Exception('断开连接')
else:
outputs.append(r)
messages[r].append(ret)
except Exception as e:
inputs.remove(r)
del messages[r]

所有给我发过消息的人(读写分离)

for w in wlist:
msg = messages[w].pop()
resp = msg + bytes('response', encoding='utf-8')
w.sendall(resp)
outputs.remove(w)

socket client:

import socket

sk = socket.socket()
sk.connect(("127.0.0.1", 9999,))

recv_bytes = sk.recv(1024)
recv_str = str(recv_bytes, encoding='utf-8')

while True:
inp = input('>>>')
sk.sendall(bytes(inp, encoding='utf-8'))
if inp == 'q':
break
print(str(sk.recv(1024),encoding='utf-8'))

三、多线程,多进程

应用程序可以有多进程和多线程运行,一般写的程序都是单进程,但线程。由于Python存在GIL,即全局解释器锁,所以对于不占用CPU的IO密集型操作可以使用多线程来提高并发,而对于占用CPU的计算密集型操作可以使用多进程来提高并发。

多线程:

import threading
import time

def f1(args):
time.sleep(1)
print(args)

def f2(args):
time.sleep(3)
print(args)

print('alex')

t = threading.Thread(target=f2, args=('Wu', )) # target指定函数名,args传进的参数
t.setDaemon(True) # true,表示主线程不等此子线程
t.start() # 不代表当前线程会被立即执行
t.join(2) # 表示主线程到此,等待 ... 直到子线程执行完毕 参数n表示主线程在此最多等待n秒

f1('eric')

posted @ 2016-07-14 10:27  摸个鱼儿  阅读(1626)  评论(0)    收藏  举报