2018.8.9
day04
目录
epoll
- 使用方法 : 代码基本与poll相同
- 将生成对象的 poll() 函数 变为p = epoll()
- 将register注册IO事件时 关注的事件类别改为epoll类别
- 区别:
- epoll 效率要高于select 和 poll
- epoll 的关注触发机制更多 -->EPOLLET(边缘触发)
from socket import * from select import * s = socket() s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) s.bind(('0.0.0.0',8888)) s.listen(5) #创建epoll对象 p = epoll() #创建地图 fdmap = {s.fileno():s} #添加关注 p.register(s,EPOLLIN | EPOLLERR) while True: #进行IO监控 #[(fileno,evnet),...] events = p.poll() for fd,event in events: if fd == s.fileno(): #从地图中找到fd对应的对象 c,addr = fdmap[fd].accept() print("Connect from",addr) #注册新的IO 维护地图 p.register(c,EPOLLIN) fdmap[c.fileno()] = c else: data = fdmap[fd].recv(1024) if not data: p.unregister(fd) #从关注移除 fdmap[fd].close() del fdmap[fd] #从地图删除 else: print(data.decode()) fdmap[fd].send('收到了'.encode()) #和poll相比就是把poll改成epoll,把POLLIN,POLLERR改成EPOLLIN,EPOLLERR
本地套接字
cookie.
- linux下文件类型:
b(块设备文件) c(字符设备文件) d(目录)
-(普通文件) l(链接文件) s(套接字文件) p(管道文件) - 作用:用于本地不同程序间进行数据传输
- 本地套接字传输流程
- 创建套接字对象
sockfd = socket(AF_UNIX,SOCK_STREAM) - 绑定套接字文件,如果文件不存在则自动创建
sockfd.bind(file) 绑定一个文件 - 监听
- 消息收发 recv send
- 创建套接字对象
cookie
os.path.exists(file)
- 功能: 判断一个文件是否存在
- 参数: 文件位置
- 返回值: 存在返回True 否则返回False
os.unlink()
os.remove()
- 功能:删除一个文件
- 参数:要删除的文件
示例:
本地套接字示例:In [1]: import os In [2]: os.path.exists('./day02.txt') Out[2]: True In [3]: os.remove('./day02.txt') In [4]: os.path.exists('./day02.txt') Out[4]: False
#unix_recv.py from socket import * import os #确定使用哪个套接字文件 sock_file = "./sock" #判断文件是否已经存在,存在删除 if os.path.exists(sock_file): os.unlink(sock_file) #创建本地套接字 sockfd = socket(AF_UNIX,SOCK_STREAM) #绑定套接字文件 sockfd.bind(sock_file) #监听 sockfd.listen(3) #消息收发 while True: c,addr = sockfd.accept() while True: data = c.recv(1024) if data: print(data.decode()) else: break c.close() sockfd.close()
#unix_send.py from socket import * sock_file = "./sock" # 创建套接字 sockfd = socket(AF_UNIX,SOCK_STREAM) #连接另外一端 sockfd.connect(sock_file) #发送消息 while True: msg = input(">>") if msg: sockfd.send(msg.encode()) else: break sockfd.close()
网络基础总结:
理论:
- OSI七层模型 tcp/ip模型
- tcp和udp的区别和特征
- 三次握手和四次握手的过程和每一次作用
- 什么是IO多路复用,IO的基本形态
- 套接字的种类,套接字类型的区别
程序实践:
- TCP套接字传输的基本模型
- UDP套接字传输基本模型
- IO多路复用select poll的使用
- HTTP协议基本原理的实现
多任务编程
多任务编程
- 意义:充分利用计算机资源,同时运行多个任务,提高程序整体的运行效率
- 定义:通过程序利用计算机的多个核心达到同时执行多个任务的目的,以此达到提升程序运行效率的目的
- 实施方案:多进程编程 多线程编程
- 并行:多个计算机核心在同时处理多个任务,这时多个任务之间并行关系
- 并发:同时运行多个任务,内核在多个任务间不断切换,达到多个任务都会被执行的处理效果,此时多个任务间是并发关系
- 进程:程序在计算机中的一次执行过程
- 程序:是一个可执行文件,是静态的,占有磁盘,不占计算机的运行资源
- 进程:进程是一个动态的过程,占有计算机资源,有一定的生命周期
同一个程序不同的运行过程是不同的进程,因为分配的资源和生命周期都不相同
进程的创建流程
- 用户启动一个程序或者调用接口发起进程创建
- 操作系统接收用户请求分配计算机资源创建资源
- 操作系统将一定状态的进程提供给用户使用
- 用户利用操作系统提供的进程完成任务
进程相关概念
cpu时间片
- 如果一个进程占有cpu此时我们称为该进程占有cpu时间片。
多个进程任务会轮流占有cpu时间片形成并发效果。
进程信息(process)
- PCB(进程控制块):进程创建后会自动在内存生产一个空间存放进程信息。
- 进程信息:进程的ID,进程占有内存的位置,创建时间,创建用户。。。
- 查看系统该进程信息:ps -aux
- PID(process ID):在操作系统中每个进程都有唯一的PID值是由系统分配的
进程特征:
- 进程是操作系统分配资源的最小单元
- 每个进程拥有自己独立的运行空间(虚拟内存空间)
- 进程之间运行相互独立互不影响
进程的状态:
- 三态
- 就绪态:进程具备执行条件,等待系统分配处理器。资源进入运行状态
- 运行态:进程占有cpu处于运行状态
- 等待态:进程暂时不具备运行条件,需要阻塞等待
- 五态(三态基础上增加新建和终止)
- 新建:创建一个新的进程,获取系统资源的过程
- 终止:进程执行结束,释放资源的过程
- ps -aux ---> STAT表示进程状态
- D 等待态 阻塞(不可中断等待)
- S 等待态 睡眠(可中断等待)
- T 等待态 暂停(暂停状态)
- R 运行态 (就绪态 运行态)
- Z 僵尸态
- + 前台进程(在终端运行)
- < 有较高优先级的进程
- N 较低优先级的进程
- l 有进程链接
- s 会话组
进程的优先级
- top :动态查看进程优先级
- < > 进行翻页 q退出
- 优先级取值范围:-20 --- 19 -20最高
- nice:以指定的优先级运行一个程序
- nice -9 ./while.py
- sudo --9 ./while.py -9优先级
#!/usr/bin/python3 表示用/usr/bin/python3 这个目录所代表的程序解释该python程序,放第一行 from time import ctime,sleep while True: sleep(2) print(ctime()) #(用这运行,程序必须要有可执行权限,可执行权限用chmod 775 while.py) #./while.py #nice -9 ./while.py #另一程序打开top查看
cookie:
- 首行添加
#! /usr/bin/python3 - 修改程序权限添加可执行权限
chmod 775 while.py - 可以直接指明路径执行
./while.py
父子进程
- 在系统中除了初始化进程,每个进程都有一个父进程,可能有0个或多个子进程,由此形成进程间的父子关系
- 便于进程管理,父进程发起创建子进程请求
- 查看进程数:pstree
- 查看父子进程PID:ps -ajx
要求:
- 什么是进程,进程和程序的区别
- 了解进程的特征和基本概念
- 理解并发和并行的区别
- 清楚进程的状态及转换
os.fork 创建进程
- pid = os.fork()
- 功能:创建进程
- 返回值:
- 失败返回一个负数
- 成功:在原有进程中返回新进程的PID号
在新进程中返回0
- 子进程会复制父进程全部内存空间包括代码段
- 子进程会从fork的下一句开始执行
- 父进程中fork返回值即为新创建子进程的PID号
- 父子进程不一定谁先执行,执行上互不干扰抢占时间片
- 使用if语句结构使父子进程执行不同的代码几乎是fork创建进程的固定结构
- 在子进程中对变量等其他内容的修改,不会影响父进程中的内容
- 子进程虽然复制父进程内容,但是也有自己的特有属性特征,比如PID号,PCB,内存区间等
示例1:
import os from time import sleep print("******************") a = 1 pid = os.fork() if pid < 0: print("Create process failed") elif pid == 0: print("This is Child process") print("a = ",a) a = 10000 else: sleep(1) print("This is parent process") print("parent a :",a)
示例2:
import os from time import sleep pid = os.fork() if pid < 0: print("create process failed") elif pid == 0: print("Child PID:",os.getpid()) print("Get parent PID",os.getppid()) else: sleep(0.5) print("Parent PID:",os.getpid()) print("Get child PID:",pid)
获取进程PID
- os.getpid()
- 功能:获取进程的PID号
- 返回值:返回进程的PID号
- os.getppid()
- 功能:获取父进程的PID号
- 返回值:返回父进程的PID号
import os from time import sleep pid = os.fork() if pid < 0: print("create process failed") elif pid == 0: print("Child PID:",os.getpid()) print("Get parent PID",os.getppid()) else: sleep(0.5) print("Parent PID:",os.getpid()) print("Get child PID:",pid) #Child PID: 13911 #Get parent PID 13910 #Parent PID: 13910 #Get child PID: 13911
程序退出
- os._exit(status)
- 功能:退出一个进程
- 参数:进程的退出状态(整数)
- sys.exit([status])
- 功能:退出一个进程
- 参数:默认为0
如果传入一个整数则同_exit()
传入一个字符串,退出时打印该字符串 - sys.exit() 可以通过捕获SystemExit异常阻止退出
import os,sys # os._exit(0) try: sys.exit("退出") except SystemExit as e: print("退出原因:",e) print("Process end") #退出原因: 退出 #Process end #sys.exit()可以通过捕获SystemExit异常阻止退出
作业:
- 进程fork理解
- 熟悉进程的理论