进程Manager
功能
数据同步,无需接收与传递参数,数据变化自动同步
用法
-
创建对象
-
m = multiprocessing.Manager()
-
调用方法获得特殊的数据对象
-
data = m.dict({"num": 0})
-
数据对象进行传递并可在另一进程内修改数据
注意
- 子进程要join一下,在主进程中要join一下,否则会报错
- 多个子进程同时修改数据会发生数据冲突,解决办法,加进程锁
代码
import multiprocessing
def func(data):
print("在子进程内")
data["num"] += 1
# print(data.get("num"))
print("结束子进程")
if __name__ == '__main__':
m = multiprocessing.Manager()
data = m.dict({"num": 0})
p = multiprocessing.Process(target=func, args=(data,))
p.start()
p.join()
print(data["num"])
进程池
-
创建进程池对象
- pool = multiprocessing.Pool(数量)
-
同步模式运行
- pool.apply(函数名,args=(参数,))
- 同步模式运行,代码效率低下
-
异步模式运行
-
pool.apply_async(函数名,args=(参数,))
-
异步模式运行,真异步模式,主进程不等待子进程
-
如果希望主进程等待子进程,办法如下:
-
pool.close(),让进程池对象的入口关闭,不再接收任务进来
-
pool.join(), 让进程池对象等待池子队列中的任务执行。未完成阻塞,完成后解阻塞
import multiprocessing import time def func(n): print(n) time.sleep(1) if __name__ == '__main__': p = multiprocessing.Pool(3) for i in range(10): p.apply_async(func, args=(i,)) p.close() p.join()
-
-
如果希望主进程等待子进程,另一种办法如下:
-
接收 pool.apply_async()对象
import multiprocessing import time def func(n): print(n) time.sleep(1) if __name__ == '__main__': p = multiprocessing.Pool(3) ret_list = [] for i in range(10): ret = p.apply_async(func, args=(i,)) ret_list.append(ret) for ret in ret_list: ret.get()
-
-
进程池版tcp服务端与客户端
开发注意事项
- 套接字的创建要在测试分支下面,否则会报错说端口重复占用
- 再次明确一下,需知哪些代码是会被另外的进程复制的
服务端代码
服务端注意事项
- 要考虑到客户端的非法关闭,强制关闭连接,意外关闭连接
- 明确,上述情况发生时—》双向连接会丢失
- 如果服务端没有错误捕获,它会仍然尝试通过一个不存在了的双向连接收发数据
- 会报错
- 要考虑到客户端的合法关闭。
- 合法关闭客户端,对于服务端而言,双向连接会解阻塞,收到空bytes数据,长度为0
- 知识点,客户端可以发送空数据。但是,服务端收不到空数据。
客户端代码
等待添加
进程池的回调函数
什么是回调函数
当前例子下
前面的函数执行的返回值是回调函数的参数
回调函数的应用
举例
pool.apply_async(add, args=(i,), callback=func)
匿名函数
什么是匿名函数
当我们在使用函数时,有些时候,不需要显式地定义函数,直接使用匿名函数更方便。
如何定义匿名函数
使用关键词lambda定义
# 匿名函数
func = lambda m:m+1
r = func(10)
print(r)
注意的事项
定义一个匿名函数
func = lambda 形参:返回值
调用函数
变量 = func(实参)
相当于
def func(形参)
return 返回值
函数的调用
变量 = func(实参)
排序
普通排序两种方式
- 使用方法
- 使用函数
升序排序与降序排序
列表包字典的排序,两种方式
-
使用方法
-
使用函数
card_list = [
{"name":"张三", "age":18},
{"name":"李四", "age":16},
{"name":"李四2", "age":12}
]
res = sorted(card_list, key=lambda e:e["age"], reverse=True)
print(res)
迭代器协议
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,
要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sun、min、max函数等)
使用迭代器协议访问对象。
名词,可迭代
指可以遍历,可以for循环
可词,可迭代对象
实现了迭代器协议的对象
名词,迭代器协议
对方内部提供了一个__next__
方法,用于两种情况
- 要么返回一个数据
- 要么抛出一个异常 StopIteration
- 如何抛出一个异常
如何把一个数据变成可迭代对象
尝试调用该对象的__iter__
方法
新挑战
用while来遍历一个列表
遍历字符串
遍历字典
遍历文件
新思路
了解for 循环的本质
三元表达式
基本三元表达式
r = 条件真时的结果 if 条件 else 条件假时的结果
列表生成式
列表生成式复习,相当于二元
高阶列表生成式,加判断生成
生成器
变身生成器表达式
方括号变圆括号
生成器函数
通过yield来进行断点
通过yield来进行数据的返回
生成器对象通过__next__
方法获取数据
案例比较
原先是卖包子提前做好一笼
然而
另一种更新鲜的方式是,麦当劳模式。点餐,等餐,用餐。
例子2
发鸡蛋给学生做为礼物
老母鸡
生成器小结