day37学习内容

上章复习回顾

黏包现象
TCP
	可靠协议、流式协议
TCP流式协议 会将一些短的数据打包在一起一起发送 从而产生黏包现象
struct模块
import struct
struct.pack()    打包
struct.unpack()  解析
ps:将非固定长度的数字打包成固定长度 并且可以反向解析出打包前数字
黏包问题的解决方案
客户端给服务端发消息

客户端
	1.制作一个真实数据相关的字典
    2. 将字典序列化并编码统计长度
    3.利用struct模块对上述长度做打包处理
    4.直接发送打包之后的数据
    5.再发送字典数据
    6.最后发送真实数据

服务端
	1.接收固定长度的报头
    2.利用struct模块反向解析出字典数据的长度
    3.接收字典数据并处理成字典
    4.根据字典中的信息接收真实数据
操作系统发展史
1.穿孔卡片
2.联机批处理系统
3.脱机批处理系统
ps:CPU利用率的发展史
多道技术
单道技术
	排队执行  效率很低
多道技术
	并发效果  大大提升CPU的使用率
    
切换+保存工作
	切换
    	1.程序有IO操作
        2.程序长时间占用
     保存状态
进程理论
进程:正在运行的程序

 进程调度算法
	1.先来先服务
    2.短作业优先
    3.时间片轮转法+多级反馈队列
并行与并发
并行
	多个任务同时执行
并发
	看上去像同时执行
高并发:评估程序同时服务客户端数量的能力
进程的三状态
就绪态
运行态
阻塞态

本章内容概要

同步与异步
用来表达任务的提交方式


同步
	提交完任务之后原地等待任务的返回结果 期间不做任何事
异步
	提交完任务之后不愿原地等待任务的返回结果 直接去做其他操作  有结果自动通知
阻塞与非阻塞
用来表达任务的执行状态

阻塞
	阻塞态
非阻塞
	就绪态、运行态
综合使用
同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(********) 效率最高
创建进程的多种方式
"""
1.鼠标双击软件图标
2.python代码创建进程
"""
from multiprocessing import Process
import time


def task(name):
    print('task is running',name)
    time.sleep(3)
    print('task is over',name)
    
"""
在不同的操作系统中创建进程底层原理不一样
	windows
		以导入模块的形式创建进程
	linux/mac
		以拷贝代码的形式创建进程

"""
# if __name__ == '__main__':
#     # p1 = Process(target=task, args=('jason',))  # 位置参数
#     p1 = Process(target=task, kwargs={'name':'jason123'})  # 关键字参数
#     p1.start()  # 异步 告诉操作系统创建一个新的进程 并在该进程中执行task函数
#     # task()  # 同步
#     print('主')

from multiprocessing import Process
import time


class MyProcess(Process):
    def __init__(self, name, age):
        super().__init__()
        self.name = name
        self.age = age
        

    def run(self):
        print('run is running', self.name, self.age)
        time.sleep(3)
        print('run is over', self.name, self.age)


if __name__ == '__main__':
    obj = MyProcess('jason', 123)
    obj.start()
    print('主')

进程join方法
from multiprocessing import Process

进程间数据隔离
同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)

from multiprocessing import Process
import time

money = 1000


def task():
    global money
    money = 666
    print('子进程的task函数查看money', money)


if __name__ == '__main__':
    p1 = Process(target=task)
    p1.start()  # 创建子进程
    time.sleep(3)  # 主进程代码等待3秒
    print(money)  # 主进程代码打印money
进程间通信之IPC机制
IPC:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取
 
from multiprocessing import Queue


q = Queue(3)  # 括号内可以指定存储数据的个数
# 往消息队列中存放数据
q.put(111)
# print(q.full())  # 判断队列是否已满
q.put(222)
q.put(333)
# print(q.full())  # 判断队列是否已满
# 从消息队列中取出数据
print(q.get())
print(q.get())
# print(q.empty())  # 判断队列是否为空
print(q.get())
# print(q.empty())  # 判断队列是否为空
# print(q.get())
print(q.get_nowait())

"""
full() empty() 在多进程中都不能使用!!!
"""


from multiprocessing import Process, Queue


def product(q):
    q.put('子进程p添加的数据')

def consumer(q):
    print('子进程获取队列中的数据', q.get())


if __name__ == '__main__':
    q = Queue()
    # 主进程往队列中添加数据
    # q.put('我是主进程添加的数据')
    p1 = Process(target=consumer, args=(q,))
    p2 = Process(target=product, args=(q,))
    p1.start()
    p2.start()
    print('主')
进程对象诸多方法
1.如何查看进程号
from multiprocessing import Process, current_process
 current_process()
 current_process().pid  
import os
 	os.getpid()
  	os.getppid()
 2.终止进程
	p1.terminate()
    ps:计算机操作系统都有对应的命令可以直接杀死进程
 3.判断进程是否存活
	p1.is_alive()
 4.start()
 5.join()
生产者消费者模型
"""回想爬虫"""
生产者
	负责产生数据的'人'
消费者
	负责处理数据的'人'

该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以)
互斥锁
模拟抢票软件

from multiprocessing import Process
import time
import json
import random


# 查票
def search(name):
    with open(r'data.json', 'r', encoding='utf8') as f:
        data = json.load(f)
    print('%s在查票 当前余票为:%s' % (name, data.get('ticket_num')))


# 买票
def buy(name):
    # 再次确认票
    with open(r'data.json', 'r', encoding='utf8') as f:
        data = json.load(f)
    # 模拟网络延迟
    time.sleep(random.randint(1, 3))
    # 判断是否有票 有就买
    if data.get('ticket_num') > 0:
        data['ticket_num'] -= 1
        with open(r'data.json', 'w', encoding='utf8') as f:
            json.dump(data, f)
        print('%s买票成功' % name)
    else:
        print('%s很倒霉 没有抢到票' % name)


def run(name):
    search(name)
    buy(name)


if __name__ == '__main__':
    for i in range(10):
        p = Process(target=run, args=('用户%s'%i, ))
        p.start()
   
"""
多进程操作数据很可能会造成数据错乱>>>:互斥锁
	互斥锁
		将并发变成串行 牺牲了效率但是保障了数据的安全
"""
僵尸进程与孤儿进程
僵尸进程
	进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
    比如进程号、进程执行时间、进程消耗功率等给父进程查看
    ps:所有的进程都会变成僵尸进程
孤儿进程:
    子进程正常运行 父进程意外死亡 操作系统针对孤儿进程回派遣福利院管理
posted @ 2022-11-18 16:59  性格如此w  阅读(25)  评论(0)    收藏  举报