第三十六次总结:进程Manager,进程池(二),反射,排序,生成器

进程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(实参)

 

反射

获取对象的属性

getattr(对象,str属性名)

对象的描述中

可以这样子简单的把汉语转换为代码

汤姆的名字 --- 汤姆.名字标识符

汤姆的颜色 ---- 汤姆.颜色标识符

 

判断对象是否有某属性

 

排序

普通排序两种方式

  • 使用方法

  • 使用函数

 

升序排序与降序排序

 

 

列表包字典的排序,两种方式

  • 使用方法

 

  • 使用函数

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)

 

 

迭代器协议

 

 

名词,可迭代

指可以遍历,可以for循环

 

可词,可迭代对象

实现了迭代器协议的对象

 

名词,迭代器协议

对方内部提供了一个__next__方法,用于两种情况

  • 要么返回一个数据

  • 要么抛出一个异常 StopIteration

    • 如何抛出一个异常

 

如何把一个数据变成可迭代对象

尝试调用该对象的__iter__方法

 

 

新挑战

用while来遍历一个列表

遍历字符串

遍历字典

遍历文件

 

新思路

了解for 循环的本质

 

三元表达式

基本三元表达式

r = 条件真时的结果 if 条件 else 条件假时的结果

 

 

列表生成式

列表生成式复习,相当于二元

高阶列表生成式,加判断生成

 

 

 

生成器

 

变身生成器表达式

方括号变圆括号

 

生成器函数

通过yield来进行断点

通过yield来进行数据的返回

生成器对象通过__next__方法获取数据

 

 

 

 

生成器小结

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值