并发编程之基于协程的高并发服务端、面向对象回顾等相关内容-41

回顾

1 线程池和进程池的shutdown
-等待池中所有任务执行完毕后关闭池(不能写在for循环中)
2 定时器
-Timer:延迟几秒后执行一个任务,Timer(时间,任务)
3 协程介绍
-单线程下实现并发,人为制造出来的,操作系统感知不到,通过保存状态和切换,理想效果是遇到io切换
   -串行执行和通过yield关键字切换,时间长短,单纯的切换反而影响效率
4 greenlet模块(初级模块)
-单纯的切换,遇到io不会切,g.switch()
5 gevent模块
-monkey.patch_all() 猴子补丁,替换
   -g1=gevent.spwan(任务)
   -g2=gevent.spwan(任务)
   -g1.join()
   -gevent.joinall([g1,g2])
7 io模型
-用户态,内核态
   -阻塞io,bio
   -NIO 非阻塞
   -I/O多路复用:目前最流行的模型,你所听到的所谓高并发的框架基本都是这个模型,ngixn,redis
  -select(1024个文件描述符)windows支持, poll(没有大小限制) ,都是在轮循
       -epoll:没有大小限制,回调机制,windows不支持
       -java的NIO和咱们说的NIO(非阻塞)不是一个东西,它就是io多路复用,New IO,Netty
   -异步I/O模型

今日内容

1 基于协程的高并发服务端
2 并发编程大串讲
3 面向对象大串讲

1 基于协程的高并发服务端

# server.py

from gevent import monkey,spawn;monkey.patch_all()

from socket import socket

def make_server(ip, port):
   server = socket()
   server.bind((ip, port))
   server.listen(5)

   while True:
       conn, addr = server.accept()
       spawn(task,conn)  # 这里还需要join吗?不能加,我们不希望它夯在这


def task(conn):
   while True:
       # bytes.upper()
       # str.upper()
       try:
           data = conn.recv(1024)
           if len(data) == 0: break
           print(data)
           conn.send(data.upper())
       except Exception as e:
           print(e)
           break
   conn.close()



if __name__ == '__main__':
   # make_server('127.0.0.1',8080)
   g=spawn(make_server,'127.0.0.1',8080)
   g.join()
# client.py

from socket import socket
from threading import Thread,current_thread

def task():
   cli = socket()
   cli.connect(('127.0.0.1', 8080))
   while True:
       ss='%s say hello'%current_thread().name
       cli.send(ss.encode('utf-8'))
       data = cli.recv(1024)
       print(data)


for i in range(5000):
   t=Thread(target=task)
   t.start()

2 并发编程大串讲

操作系统发展史(了解)
多道技术(了解)
进程调度(了解)
-进程状态:就绪,执行,阻塞
进程三状态(就绪,阻塞,运行)
同步异步 阻塞非阻塞:异步+非阻塞
-同步是任务提交了,等待执行完成
   -异步是任务提交了,不等待执行完成,我自己去干自己的事,任务完成有回调
   -阻塞:程序运行的状态阻塞(io操作)
   -非阻塞:程序一直在运行的状态
创建进程的两种方式(重点)
-资源分配的最小单位
   -两种方式
   -windows下开进程,在main函数下
进程join方法
-等待子进程执行完成,父进程再继续执行
进程间数据相互隔离
-因为开启一个进程,其实本身就是拉起一个python解释器,把进程跑在里面
僵尸进程与孤儿进程
-进程死了,还有数据每回收
   -父进程死了,子进程就是孤儿进程
进程对象及其他方法
-进程id号,父进程id号,关闭进程,查看进程是否存活
守护进程
-主进程结束,守护进程跟着结束
互斥锁
-Lock
   -获得锁
   -释放锁
队列介绍
-进程Queue
   -放值,取值
   -放满了,取没了(阻塞,报错)
IPC机制
-进程间通信(队列机制)
GIL与普通互斥锁的区别
-全局解释器锁,垃圾回收线程,不是数据安全的,线程必须拿到GIL锁,才能执行
   -GIL不能保证我们自己的数据安全,自己的数据安全需要自己处理锁
   -io密集型:线程
   -计算密集型:进程
多线程与多进程比较
-进程是资源分配的最小单位
   -cpu执行(调度)的最小单位
   -每个进程里至少有一条线程
死锁现象
-A这把锁,连续获得,第二次获得,就会夯住,形成死锁
   -A线程已经获取A锁,等待去获取B锁,但是B锁被B线程获得,B线程在等待A锁
递归锁(可重入锁)
-同一条线程,可以重复获得这把锁,每获得一次数字加一,只有计数为0,其他线程才能获得
   -解决死锁现象的第二种:A和B是同一把锁
信号量
-运行多条线程同时修改数据
Event事件
-发一个信号event.set(),原来在等待的(event.wait())线程会继续执行
线程q
-三种,先进先出,先进后出,优先级(越小)
池的概念
-用来做缓冲,不会一次性创建出很多(进程,链接),池子多大,最多就创建多少
线程池
-类不一样,用法完全一样
   from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
   pool=ThreadPoolExecutor(5)
   pool.submit(任务).add_done_callback(函数)
   
协程基本原理
-单线程下实现并发,程序员制造出来的,切换+保存状态
gevent模块
协程实现tcp并发
io模型介绍
阻塞io模型
非阻塞io模型理论
io多路复用
asyncio模块
io模型

3 面向对象大串讲

类与对象
-class Person():
   -p=Person()
属性查找
-p.name:先找对象自己,找不到去类中找,再找不到报错
类属性和对象属性
-分别再不同的名称空间
# class Person:
#     name='lqz'
#
# p=Person()
# p.name='egon' # 只是改了对象自己名称空间中的name,不会影响到类的name
# print(p.name)
#
# p1=Person()
# print(p1.name)
# # 就想改类中的name,如何改
# Person.name='xxx'
# print(p1.name) # xxx
#
# print(p.name) # egon
对象的绑定方法
-特殊之处,对象来调用,会自动传值,把对象自己传过来,当那个对象来调用,self就是谁
   -类也可以来调用,类调用就是普通函数,有几个参数就要传几个参数
# class Person:
#     name = 'lqz'
#
#     def play(self):
#         print(self.name)
#
# # 特殊之处,对象来调用,会自动传值,把对象自己传过来,当那个对象来调用,self就是谁
#
# p=Person()
# p.play()
# p.name='egon'
# p.play()

# 类也可以来调用,类调用就是普通函数,有几个参数就要传几个参数

# Person.play([1,2]) # 普通函数,怎么传值都行
函数和方法
# from types import FunctionType, MethodType
#
# class Person:
#     name = 'lqz'
#
#     def play(self):
#         print(self.name)
#
# print(isinstance(Person.play, FunctionType)) # 类来调用,play就是个普通函数,打印出True
# print(isinstance(Person.play, MethodType)) # 不是方法,打印出false
# p=Person()
# print(isinstance(p.play, FunctionType)) # False
# print(isinstance(p.play, MethodType)) # True

类与数据类型(类即类型)
# class Person:
# #     name = 'lqz'
# # l=[1,2,3]
# # dic={'name':'lqz'}
# # p=Person()
# # print(type(l))
# # print(type(p))

类的继承(python支持多继承)
# class Human:
#     name = 'lqz'
#
#     def test(self):
#         print('test')
#
#
# class Person(Human):
#     name = 'egon'
#
#
# # print(Person.name)
# ## 查找顺序
# p = Person()
# print(p.name)


# 对象自己找,类里找,父类找,父类。。(mro列表)
继承后属性查找顺序
派生(子类中新定义的属性或方法)
super()特殊的对象
# class Human:
#     name = 'lqz'
#     def test(self):
#         print('test')
# class Animal:
#     def test222(self):
#         print('test2222')
# class Person(Human,Animal):
#     name='egon'
#     def test(self):
#         super().test() # super代指Human的对象
#         super().test222()   # super代指Animal的对象
#         #特殊对象,很特殊,代指父类对象,但是分情况代之的不一定(mro列表)是哪个父类

多继承下的super(FatBossGril.__mro__)
组合(属性的值是指向另外一个类的对象)
# class Human:
#     name = 'lqz'
#
#     def __init__(self, name):
#         self.name = name
#
#
# class Animal:
#     pass
#
#
# h = Human('lqz') # 这就是组合,name是str对象
# print(h.name)
# h1 = Human(Animal()) # 这就是组合,name是Animal对象
# print(h1.name)
多态与多态性
-多态指的是一类事物有多种形态
-多态性:一种调用方式,不同的执行效果
# -多态指的是一类事物有多种形态
# -多态性:一种调用方式,不同的执行效果

# class Human:
#     def test(self):
#         print('人玩')
#
#
# class Animal:
#     def test(self):
#         print('动物玩')
#
# def print_test(obj):
#     obj.test()
#
# h=Human()
# a=Animal()
# print_test(h)
# print_test(a)

封装,隐藏属性
# class Human:
#     name = 'lqz'
#
#     def __init__(self, name):
#         self.name = name
#
#
# class Animal:
#     pass
# a=Animal()
# h=Human(name=a) # 把一个对象放到另一个对象中就叫封装
# # 有什么用?只需要拿到一个对象,里面就有很多属性和方法
#
# ## 隐藏属性,把属性或者方法隐藏起来,只在内部用,不对外提供
# ## 不管是属性还是方法 __开头就隐藏了
# ## 外部通过   _类名__属性/方法(其他语言,调不到就是调不到)
# ## 外部想用,开发一个接口(别的方法,加限制你再用)

property
类方法,对象方法,静态方法
# class Human:
#     # 对象方法(对象的绑定方法),对象来调用,自动把对象传过来
#     def __init__(self, name):
#         self.name = name
#
#     # 类方法(类绑定方法),类来调用,自动把类传过来
#     @classmethod
#     def test(cls):
#         print('类方法')
#
#     # 静态方法,对象,类都可以来调用,没有自动传值,就是个普通函数
#     @staticmethod
#     def test2():
#         print('静态方法')
isinstance和issubclass
isinstance与type
# isinstance:判断对象是不是某个类的实例
# issubclass:判断类父子关系
# type

# class Animal:
#     pass
# class Human(Animal):
#     # 对象方法(对象的绑定方法),对象来调用,自动把对象传过来
#     def __init__(self, name):
#         self.name = name
#
# h=Human('lqz')
#
# print(type(h)) #Human
# print(isinstance(h,Human))
# print(isinstance(h,Animal))
反射getattr,setattr,hasattr,delattr
# 动态的从对象中获取值(属性或者方法),或者放,判断对象中有没有这个值,动态的从对象中删除值

'''
__setattr__和__delattr__和__getattr__
-添加/修改属性会触发它的执行
-删除属性的时候会触发
-只有在使用点调用属性且属性不存在的时候才会触发
-递归现象:object.__setattr__(self,'storage',{})
'''


# class Person():
#     def __setattr__(self, key, value): # 对象.赋值会触发 a.name='lqz' name给key,lqz给value
#         print('set')
#
#     def __getattr__(self, item):# 对象.取值会触发 a.name name给item,return 1
#         print('get')
#         return 1
#
#     def __delattr__(self, item):# del 对象.属性 会触发
#         print('delete')
#
#
# p = Person()
# p.name
# print(p.name)
__setitem__和__getitem和__delitem__(没讲)
__init__和__new__(不讲了)
其他魔法方法(不讲了)
元类(不讲了)
-type:所有类的类,但是继承object
-object:所有类的父类,同时由type生成
# 字典,不支持 . 赋值,取值,想让它支持

# class Mydic(dict):
#     def __setattr__(self, key, value): # 对象.赋值会触发
#         self[key]=value
#
#     def __getattr__(self, item):# 对象.取值会触发
#         return self[item]
# #
# #
# d=Mydic(name='lqz',age=18)
#
# print(d['name'])
# print(d['age'])
# #
# d.name='egon'
# #
# # print(d['name'])
# print(d.name)




# 普通对象不支持中括号的取值和赋值除非继承字典,不继承字典,但是让他支持[]取值赋值,让它支持()


# class Person():
#     def __setattr__(self, key, value): # 对象.赋值会触发
#         print('set')
#
#     def __getattr__(self, item):# 对象.取值会触发
#         print('get')
#         return 1
#
#     def __delattr__(self, item):# del 对象.属性 会触发
#         print('delete')


一切皆对象之函数对象
def test():
#     print('xxx')
#
# test.name='lqz'
# test()
# print(test.name)
# # 正是因为函数是对象,所有,它可以赋值给变量,可以当作返回值,可以当作参数传递

 

posted @ 2020-08-31 20:10  投降输一半!  阅读(173)  评论(0编辑  收藏  举报