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  摸个鱼儿  阅读(1577)  评论(0编辑  收藏  举报