博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python day30
阅读量:5244 次
发布时间:2019-06-14

本文共 4775 字,大约阅读时间需要 15 分钟。

今日内容


内容回顾


大文件上传

服务端

  • 1.socket创建TCP服务
  • 2.连接循环
  • 3.通信循环
    • 接收固定长度的字典的报头
    • 解析获取字典数据的真实长度
    • 接收字典数据,解码,反序列化成字典
    • 从字典中获取文件大小,以及文件名等其他信息
  • 4.循环接受文件数据
    • 文件操作,接收一行就往文件中写入一行

客户端

  • 1.socket客户端代码
  • 2.利用os.listdir获取文件夹中的所有文件名
  • 3.循环打印,供用户选择想要上传的文件,以及用户选择是否符合要求
  • 4.根据用户选择以及os.path.join方法拼接用户想要上传的文件绝对路径
  • 5.根据文件路径获取文件大小os.path.getsize()
  • 6.定义一个发送给服务端的字典
  • {"file_name":用户选择的文件名,"file_size":文件大小  ...额外的键值信息}
  • 7.制作字典的报头(序列化,编码)
  • 8.发送字典的报头
  • 9.发送字典的数据
  • 10.发文件(文件操作,一行行读取并发送,因为TCP协议是流式协议)

多道技术

1.空间上的复用

  • 多个程序共用一套计算机硬件

2.时间上的复用

  • 切换+保存状态
    • 1.当一个程序遇到IO操作 操作系统会剥夺该程序的cpu执行权限(提高了cpu的利用率 并且也不影响程序的执行效率)
    • 2.当一个程序长时间占用cpu 操作系统也会剥夺该程序的cpu执行权限(降低了程序的执行效率)
  • 并发:看起来像同时运行的就可以
  • 并行:真正意义上的同时执行
    • 单核的计算机能不能实现并行,但是可以实现并发

进程的同步与异步

程序:一坨代码

进程:正在运行的程序

同步异步:表示的是任务的提交方式

  • 同步:任务提交之后 原地等待的任务的执行并拿到返回结果才走 期间不做任何事(程序层面的表现就是卡住了)
  • 异步:任务提交之后 不再原地等待 而是继续执行下一行代码(结果是要的 但是是用过其他方式获取)

阻塞非阻塞:表示的程序的运行状态

  • 阻塞:阻塞态
  • 非阻塞:就绪态 运行态

强调:同步异步 阻塞非阻塞是两对概念 不能混为一谈


创建进程的两种方式

windows创建进程会将代码以模块的方式,从上往下执行一遍

linux会直接将代码完完整整的拷贝一份,fork一份

第一种方式:

  • windows创建进程一定要在__main__ 代码块内创建,否则报错

from muliprocessing import Processimport time​def test(name):    print('%s is running' %name)    time.sleep(3)    print('%s is over' %name)    # windows创建进程一定要在if __name__ == '__main__':代码块内创建,否则报错 if __name__ == '__main__':    p = Process(target=test,args=('egon',))  # 创建一个进程对象    p.start()  # 告诉操作系统,帮你创建一个进程    print('主')# 主# egon is running# egon is over

总结:

  • 创建进程就是在内存中重新开辟一块内存空间,将允许产生的代码丢进去;而且一个进程对应在内存就是一块独立的内存空间
  • 进程与进程之间数据是隔离的,无法直接交互,但是可以通过某些技术实现间接交互

第二种方式:

from muliprocessing import Processimport time​class MyProcess(Process):    def __init__(self,name):        super().__init__()        self.name = name​def run(self):    print('%s is running' %self.name)    time.sleep(3)    print('%s is over' %self.name)    if __name__ == '__main__':    p = MyProcess(target=test,args=('egon',))    p.start()    print('主')# 主# egon is running# egon is over

join方法

from muliprocessing import Processimport time​def test(name,i):    print('%s is running' %name)    time.sleep(i)    print('%s is over' %name)    if __name__ == '__main__':    p_list = []    start_time = time.time()    for i in range(3):        p = Process(target=test,args=('进程%s'%i,i))    # 主进程代码等待字进程运行结束才继续运行        p.start()  # 仅仅是告诉操作系统帮你创建一个进程,至于先后顺序则是随机的        p_list.append(p)    for p in p_list:        p.join()  # 主进程代码等待子进程运行结束    print('主')    print(time.time() - start_time)    # 进程0 is running    # 进程0 is over    # 主    # 所有步骤花费的时间显示

进程间数据是隔离的

from muliprocessing import Processimport time​money = 100  # 主进程内的money​def test():    global money    money = 888888  # 子进程内的money​if __name__ == '__main__':    p = Process(target=test)    p.start()    p.join()    print(money)  # 100

进程对象及其他方法

在操作系统cmd终端中可以通过tasklist + pid码来查询

from muliprocessing import Process,current_processimport osimport time​def test(name):    print('%s is running' %name,current_process().pid)    print('%s is running' %name,'子进程%s' %os.getpid(),'父进程%s' %os.getppid())    time.sleep(30)    print('%s is over' %name)​if __name__ == '__main__':    p = Process(target=test,args=('egon',))    p.start()    p.terminate()  # 杀死当前进程,其实是告诉操作系统帮你杀死一个进程    time.sleep(0.1)    print(p.is_alive())  # 判断进程是否存活 返回True:马上杀死,False:已杀死    print('主',current_process().pid)    print('主',os.getpid(),'主主进程:%s' %os.getppid())    # 主 23040 主主进程:20352    # egon is running 21991    # egon is over

僵尸进程

父进程回收子进程资源的两种方式

  • 1.join方法
  • 2.父进程正常死亡

PS:所有的进程都会步入僵尸进程


孤儿进程

  • 子进程没死,父进程意外死亡
  • 针对linux,会有一个儿童福利院(init),如果父进程意外死亡,他所创建的子进程都会被福利院收养

守护进程

from muliprocessing import Processimport time​def test(name):    print('%s总管正常或者' %name)    time.sleep(3)    print('%s总管正常死亡' %name)    if __name__ == '__main__':    p = Process(target=test,args=('egon',))    p.daemon = True  # 将该进程设置为守护进程,而且这句话必须放在start语句之前,否则会报错    p.start()    print('皇帝jason寿终正寝')    # 皇帝jason寿终正寝

互斥锁

定义:当多个进程操作同一份数据时,会造成数据的错乱,这个时候必须加锁处理,将并发变成串行,虽然降低了效率,但是提高了数据的安全

注意:

  • 1.锁不要轻易使用,容易造成死锁现象
  • 2.只在处理数据的部分加锁,不要在全局加锁

设计一个模拟抢票软件

from muliprocessing import Process,lockimport timeimport json​# 查票def search(i):    with open('data','r',encoding='utf-8') as f:        data = f.read()    t_d = json.loads(data)    print('用户%s查询余票为:%s' %(1,t_d.get('ticket')))    # 买票def buy(i):    with open('data','r',encoding='utf-8') as f:        data = f.read()    t_d = json.loads(data)    time.sleep(1)    if t_d.get('ticket') > 0:        # 票数减1        t_d['ticket'] -= 1        # 更新票数        with open('data','w',encoding='utf-8') as f:            json.dump(t_d,f)        print('用户%s抢票成功!'%i)    else:        print('没票了!)              def run(i,mutex):    search(i)    mutex.acquire()  # 抢锁,只要有人抢到了锁,其他人必须等待该人释放锁    buy(i)    mutex.release()  # 释放锁              if __name__ == '__main__':    mutex = Lock()  # 生成了一把锁    for i in range(10):        p = Process(target=test,args=('egon',))         p.start()

转载于:https://www.cnblogs.com/zhukaijian/p/11328029.html

你可能感兴趣的文章
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
python针对excel的读写操作-----openpyxl
查看>>
最后几本书,不珍藏了。
查看>>
Js时间处理
查看>>
Java项目xml相关配置
查看>>
按钮实现A标签新窗口打开(不用window.open)
查看>>
三维变换概述
查看>>
第三次作业
查看>>
Python的classmethod和staticmethod区别
查看>>
Ubuntu12.04 英文环境下使用ibus输入中文并自动启动输入法
查看>>
SpringMVC 拦截器HandlerInterceptor(一)
查看>>
mvc知识应用
查看>>
数据结构之排序三:插入排序
查看>>
Class.forName(),classloader.loadclass用法详解
查看>>
vue route 跳转
查看>>
Device Tree Usage
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
POJ 1220 高精度/进制转换
查看>>
cocos2d-x中CCLabelAtlas的小图片拼接
查看>>