Linux下文件类型: bcd -lsp b(块、设备文件) c(字符设备文件) d(目录) -(普通文件) l(链接文件) s(套接字文件) p(管道文件) kill -sig pid:通过pid发送信号杀死指定进程 kill -l:查看操作系统内所所有sig信号 ps -aux —> STAT表示进程状态 信号: SIGHUP 断开链接 SIGINT Ctrl + c SIGQUIT Ctrl + \ SIGTSTP Ctrl + z SIGKILL 终止进程且不能被处理 SIGSTOP 暂停进程且不能被处理 SIGALRM 时钟信号 SIGCHLD 子进程改变状态时父进程会收到此信号 OSI七层模型 —–> 网络通信的标准化流程 应用层: 提供用户服务,具体的内容由特定的程序规定 表示层: 提供数据的加密和压缩优化 会话层: 确定建立应用链接,选择传输服务 传输层: 提供数据传输服务,进行流量控制 网络层: 路由选着,网络互联 链路层: 提供链路交换,具体消息的发送 物理层: 物理硬件,接口,网卡的规定网络协议:应用层:TFTP(文件传输)、HTTP(超文本传输协议)、DNS(域名解析)、SMTP(邮件传输)传输层:TCP、UDP网络层:IP物理层:IEEEIP地址本地使用:127.0.0.1 或 “localhost”网络地址:“0.0.0.0” 或 “172.168.40.53”IPv4: 点分十进制 例如:192.168.1.3 取值0~255(32位)IPv6: 128位 socket模块: ifconfig:查看本机IP (ens33:本地IP lo:本地回还) ipconfig:windoes中 socket.gethostname() : 获取本机主机名 socket.gethostbyname(‘tedu’) : 利用主机名获取ip socket.gethostbyname(‘localhost’): 获取本地ip socket.gethostbyaddr(‘127.0.0.1’) 访问主机IP地址 socket.inet_aton(‘192.168.1.2′) IP十六进制转换 socket.inet_ntoa(b’\xc0\xa8\x01\02’) IP十进制转换 socket.getservbyname(‘ssh’) 获取应用程序的端口创建TCP服务端套接字:sockfd.socket(sock_family = AF_INET, sock_tpye = SOCK_STREAM, proto = 0) sockfd.bind(addr) 绑定地址 sockfd.listen(n) 设置监听套接字 connfd,addr = sockfd.accept() 等待接受客户端链接 data = connfd.recv(buffersize) 接收消息 connfd.send(data) 发送消息 sockfd.close() 关闭套接字创建TCP客户端套接字:sockfd.socket(sock_family = AF_INET, sock_tpye = SOCK_STREAM, proto = 0) sockfd.bind(addr) 绑定地址 sockfd.connect(addr) 链接服务端 data = connfd.recv(buffersize) 接收消息 connfd.send(data) 发送消息 sockfd.close() 关闭套接字 创建UDP客户端套接字: sockfd.socket(sock_family = AF_INET, sock_tpye = SOCK_DGRAM, proto = 0) sockfd.bind(addr) 绑定地址 data = sockfd.recvfrom(buffersize) 接收消息 sockfd.sendto(data, addr) 发送消息 sockfd.close() 关闭套接字创建UDP客户端套接字: sockfd.socket(sock_family = AF_INET, sock_tpye = SOCK_DGRAM, proto = 0) data = sockfd.recvfrom(buffersize) 接收消息 sockfd.sendto(data, addr) 发送消息 sockfd.close() 关闭套接字 创建本地套接字服务端: sockfd = socket(AF_UNIX, SOCK_STREAM) sockfd.bind(file) 绑定套接字文件 sockfd.listen(3) 监听 connfd,addr = sockfd.accept() 等待链接 connfd.recv(buffersize) 接收消息 connfd.send(data) 发送消息 sockfd.close() 关闭套接字创建本地套接字客户端: sockfd = socket(AF_UNIX, SOCK_STREAM) sockfd.connect(sock_file) 链接服务端 connfd.recv(buffersize) 接收消息 connfd.send(data) 发送消息 sockfd.close() 关闭套接字 套接字属性: sockfd.type 返回套接字类型 sockfd.family 返回地址类型套接字方法: sockfd.fileno() 获取套接字的文件描述符 sockfd.getsockname() 获取套结字绑定的地址 sockfd.getpeername() 获取链接套接字客户端的地址 sockfd.setsockopt(level,optname, value) 设置端口可立即重用 sockfd.setblocking(False) 将套接字设置为非阻塞状态 sockfd.settimeout(sec) 设置套接字的超时时间 select模块: IO多路复用,阻塞等待监控的IO事件发生rs, ws, xs = select(rlist, 等待处理的IO wlist 想要主动处理的IO xlist[, 出错希望去处理的IO timeout]) 超时检测p = select.poll 创建poll对象p.register(s, POLLIN | PLLERR) 注册关注的IOevents = p.poll() 监控关注的IO事件 multiprocessing模块: 创建进程对象Process(target, 要绑定的函数 name, 给进程起的名称 args, 元组给target函数位置传参 kwargs) 字典给target函数键值传参p.start() 启动进程terget绑定函数p.join([timeout]) 阻塞等待子进程退出p.name 获取进程名(属性)p.daemon 设置为True主进程结束杀死所有子进程(必须start()前设置)p.is_alive() 判断进程是处于alive状态(存活)p.pid 获取创建进程的pid号(属性) pool = pool(x) 创建进程池对象(进程池大小)pool.apply_async(fun, 要执行的函数(异步执行) args, 以元组形式为fun传参 kwds) 以字典形式为fun传参pool.apply(fun, args, kwds) (同步执行)r = pool.map(fun,range(6)) 将要执行的事件放入进程池pool.close() 关闭进程池pool.join() 回收进程池 fd1,fd2 = Pipe(duplex=True) 创建管道(Flase:fd1只读,fd2只写)fd.recv() 从管道读取信息空则阻塞fd.send(data) 向管道写入内容满则阻塞 q = Queue(maxsize=0) 创建队列对象(存放多少条消息)q.put(data, 存入消息(支持Python数据类型) [block, 默认阻塞 False:非阻塞 timeout]) block为True是表示超时检测data = q.get([block,timeout]) 取出消息q.full() 判断队列是否为满q.empty() 判断队列是否为空q.qsize() 获取队列中消息的数量q.close() 关闭队列 shm = Value(ctype, 创建共享内存共享空间 obj) ctype字符串:(C语言数据类型),obj初始数据shm.value 表示共享内存的值(可以赋值)shm = Array(ctype,obj) 创建共享内存共享空间 sem = Semaphore(num) 创建信号量sem.acquire() 将信号量减1 0时阻塞sem.release() 将信号量加1sem.get_value() 获取当前信号量的值(数量) e = Event() 创建Event事件对象e.wait([timeout]) 阻塞进程 直到事件对象被sete.set.() 让事件对象变为被设置状态e.clear() 使事件对象清除设置状态e.is_set() 判断当前事件是否被set Lock = Lock() 创建锁对象lock.acquire() 上锁lock.release() 解锁 threading 模块: 创建线程对象threshold.Thread(target, 线程函数 name, 线程名字 args, 元组给线程函数位置传参 kwargs) 字典给线程函数位置传参t.start() 启动线程t.join() 回收线程t.name 线程名t.daemon = True 主线程退出分支线程也退出t.setDaemon(True) 主线程退出分支线程也退出t.isDaemon 查看daemon值t.setName(“name”) 设置线程名称t.is_alive() 查看线程状态threading.currentThread() 获取当前进程对象 e = threading.Event() 创建Event事件对象e.wait([timeout]) 事件阻塞e.set() 设置事件e.clear() 清除事件 lock = threading.Lock() 创建锁对象lock.acquire() 上锁lock.release() 解锁 socketserver集成并发模块:StreamRequestHandler 处理tcp请求DatagramRequestHandler 处理udp请求 ForkingMixIn 创建多进程ThreadingMixIn 创建多线程 TCPServer 创建tcp serverUDPServer 创建udp server ForkingTCPServer ForkingMixIn + TCPServer ForkingUDPServer ForkingMixIn + UDPServer ThreadingTCPServer ThreadingMixIn + TCPServer ThreadingUDPServer ThreadingMixIn + UDPServer signal模块:signal.alarm(sec) 设置时钟信号给自己SIGALRM信号signal.pause() 阻塞进程,等待一个信号signal.signal(sig, 要处理的信号 handler) 处理方法(SIG_DFL:默认 SIG_IGN:忽略 func:自定义函数) sys模块补充: sys.argv 获取从命令行获取的参数内容列表 sys.stdin 0 标准输入IO文件描述符 sys.stdout 1 标准输出IO文件描述符 sys.stderr 2 错误IO文件描述符 sys.exit([status]) 退出一个进程(状态:退出提示字符串)字符串方法补充: S.splitlines 按行分隔 os模块补充:os.path.exists(file) 判断一个文件是否存在os.remove(file) 删除文件os.unlink(file) 删除文件pid = os.fork() 创建进程 失败-1 成功0os.getpid() 获取进程的PID号os.getppid() 获取父进程的PIDos.exit(status) 退出一个进程(状态:整数 默认0)pid,status = os.wait() 塞等待处理子进程的退出os.WEXITSTATUS(status) 获取原来退出状态pid,status = os.waitpid(pid,option) 阻塞等待处理子进程的退出os.path.getsize(‘./1.txt’) 读取文件的大小os.kill(pid,sig) 发送一个信号给某个进程os.listdir(path) 获取指定目录文件列表os.path.isfile() 判断一个 文件是否为普通文件os.path.isdir() 判断一个文件是否为目录 传输层服务: 面向连接的传输服务(tcp协议): 传输特征: 可靠的数据传输: 可靠性:无失序、无差错、无重复、无丢失、无重复 在数据传输前和传输后需要建立连接和断开链接 面向传输服务建立连接的过程:‘三次握手’ 1.客户端向服务器发送链接请求 2.服务器接受到请求进行确认,返回确认报文 3.客户端收到服务器回复最终确认链接 面向传输服务断开链接的过程:‘四次挥手’ 1.主动方发送报文,告知被动方要断开链接 2.被动方回复报文,表示已经接受到请求,准备断开 3.被动方再次发送报文,表示准备处理就绪,可以断开 4.主动方发送确认报文,断开链接 应用情况: 适用于传输较大的内容或文件,网络良好, 需要保证传输可靠性的情况 e.g. 信息聊天,文件上传下载,邮件,网页获取 面向无连接的传输服务(udp协议): 不保证传输的可靠性没有建立连接和断开的过程数据的收发比较自由适用情况: 网络情况较差,对可靠性要求不高,收发消息的两端 e.g.:网络视频,群聊,广播等 收发函数特性: recv特征: 如果建立的另一端链接被断开, 则recv立即返回空字符串 recv是从接受缓冲区取出内容,当缓冲区为空则阻塞 recv如果一次接受不完缓冲区的内容,下次执行会自动接受 send特征: 如果发送的另一端不存在则会产生pipe…异常send是从发送缓冲区发送内容当缓冲区为满则堵塞 http协议: 超文本传输协议 用途: 网站中浏览区器网页的获取,基于网站事物数据传输 编写基于http协议的数据传输 特点: 1.应用层协议,传输层使用tcp服务 2.简单、灵活,可以使用多种编程语言操作 3.无状态的协议,既不用记录用户的输入内容 4.http1.1 —> http2.0(还没发布) 技术的成熟和稳定性 http请求(request): 1.请求格式: 1)请求行:说明具体的请求类别和内容 GET /index.html /HTTP/1.1 请求类别 请求内容 协议版本 2)请求类别: GET:获取网络资源POST:提交一定的附加数据HEAD:获取相应头PUT:更新服务器资源DELETE:删除服务器资源CONNECT:未使用TRACE:用于测试OPTIONS:获取服务器性能信息 2.请求头:对请求的具体描述 Accept:text/html 每一个键值对占一行,描述了一个特定信息 3.空行 4.请求体:具体的参数或提交的内容 get参数或者post提交的内容 http响应(response): 1.响应格式: 1)响应行:反馈具体的响应情况 HTTP/1.1 20 OK 版本协议 响应码 附加信息 3)响应码: 1xx:提示信息,表示请求已经接收 2xx:响应成功 3xx:响应需要定向 4xx:客户端错误 5xx:服务器端错误 3)常见响应码: 200 成功 404 请求内容不存在 401 没有访问权限 500 服务器未知错误 503 服务器暂时无法执行 2.响应头:对响应内容的具体描述 3.空行 4.响应体: 将客户端请求内容进行返回 IO多路复用定义:通过一个监测,可以同时监控多个IO事件的行为,当那个IO可以执行,让这个IO事件发生同时监控多个IO事件,当哪个IO事件准备就绪就执行哪个IO事件此时形成多个IO时间都可以操作的现象,不必逐个等待执行IO准备就绪:IO事件即将发生时的临界状态是不可逆转的在程序中存在的IO事件中选择要监测的事件创建监测,将监测的IO事件注册等待监测的IO事件发生,判断是什么事件处理相应的IO poll方法实现IO多路复用: 1.创建poll对象: p = select.poll 2.注册关注的IO: p.register(s, POLLIN | PLLERR) 不关注: p.unregister(s) 事件类别: POLLIN POLLOUT POLLERR POLLHUP POLLPRI rlist wlist xlist 断开 紧急处理 3.监控IO: events = p.poll() 功能:监控关注的IO事件 返回值: 返回发生IO事件 events是一个列表[(fileno, evnet), (), ()….] 每个就绪IO对应一个元组(描述符,就绪事件) IO地图:{s.fileno():s} 4.处理IO事件 位运算: 按照二进制位进行位运算操作 & 按为与 |按位或 ^按位异或 << 左异 >>右移 11 1011 14 1110 & 1010 有0得0 | 1111 有1得1 ^ 0101 相同为0不同为1 11 << 2 == 44 右侧补零(乘2乘2次) 14 >> 2 == 3 挤掉右侧的数字(地板除2除2次)使用: 1.在低层硬件时操作寄存器 2.做标志位的过滤 多任务编程: 意义:充分利用计算机资源,同时运行多个任务,提高程序整体的运行效率 定义:通过程序利用计算机的多个核心达到同时执行多个任务的目的因此达到提升程序运行效率的目的 实施方案:多进程编程多线程编程 并行: 多个计算机核心在同时处理多个任务,这时多个任务之间是并行关系 并发: 同时运行多个任务,内核在多个任务之间的不断切换,达到多个任务都会执行的处理效果此时多个任务之间的并发关系 程序: 是一个可执行文件,是静态的,只占有磁盘 不占用计算机运行资源进程: 程序在计算机中的一次执行过程 是一个动态过程,占有一定的计算机资源 有一定的生命周期注: 同一个程序不同的运行过程是不同的进程, 因为分配的资源和生命周期都不同 进程的创建过程: 1.用户启动一个程序,或是调用接口发起进程创建 2.操作系统接收用户请求分配计算机资源创建进程 3.操作系统将一定状态的进程提供给用户使用 4.用户利用操作提供的进程完成任务 CPU时间片: 如果有个进程占有CPU此时我们称为该进程占有CPU的时间片 多个进程任务或轮流占有CPU时间片并形成并发效果 进程信息(process) PCB(进程控制块): 进程创建后 会自动在内存中产生一个空间存放进程信息 进程信息: 进程ID 进程占有内存的位置 创建时间、创建位置查看系统进程信息:ps -aux PID(process ID): 在操作系统中每个进程都有唯一的PID值是由系统分配的进程特征: 进程是操作系统分配资源的最小单元 每个进程拥有自己独立的运行空间(4个G的虚拟内存空间) 进程之间相互独立各不影响 进程的状态: 三态: 就绪状态: 进程具备执行条件,等待系统分配处理器资源进入运行态 运行态: 进程占有CPU处于运行状态 等待态: 进程暂时不具备运行条件,需要阻塞等待 五态: 在三态的基础上增加新建和终止态 新建: 创建一个新的程序,获取系统资源的过程 终止: 进程执行结束,释放资源的过程 ps -aux —> STAT表示进程状态: D 等待态 阻塞 不可中断等待态 S 等待态 睡眠 可中断等待态 T 等待态 暂停 暂停执行 R 运行态(就绪态) Z 僵尸 + 前台进程(在终端运行) < 有较高优先级的进程 N 较低优先级的进程 s 回话组 l 有进程链接进程的优先级: top 查看进程运行态优先级 取值范围:-20~19 -20最高 nice: 以指定的优先级运行一个程序 nice -9 ./hello.py 以9的优先级运行 sudo nice –9 ./hello.py 以-9优先级运行 首行添加 #! /usr/bin/python3 指定执行器 执行:./hello.py 修改程序权限添加可执行权限 chmod 775 hello.py 孤儿进程 : 当父进程先于子进程退出,此时子进程就会成为孤儿进程。 * 孤儿进程会被系统指定进程收养,即系统进程会成为孤儿 进程新的父进程。系统进程会自动处理孤儿进程退出状态 僵尸进程 : 子进程先于父进程退出,父进程没有处理子进程的退出状态,此时子进程就会成为僵尸进程* 僵尸进程会滞留部分PCB信息在内存中,大量的僵尸进 程会消耗系统的内存资源,所以要尽量避免僵尸进程产生 如何避免僵尸进程产生?* 父进程先退出* 父进程处理子进程退出状态* 创建二级子进程 进程池技术: 产生原因: 如果有大量的任务需要多进程完成,而调用周期比较短且需要频繁创建此时可能产生大量进程频繁创建销毁的情况 消耗计算机资源较大 使用方法: 1.创建进程池,在池内放入适当数量的进程2.将事件封装成函数。放入到进程池3.事件不断运行,直到所有放入进程池事件运行完成4.关闭进程池,回收进程 同步互斥机制 目的: 解决对共有资源产生的资源争夺 临界资源: 多个进程或线程都可以操作的资源 临界区: 操作临界资源的代码段 同步: 同步是一种合作关系,为完成某个任务,多进程或者多个线程之间形成的一种协调按照约定执行,相互告知,共同完成任务 互斥: 互斥是一种制约关系,当一个进程或者线程进入临界区操作资源时采用上锁的方式,阻止其他进程操作,直到解锁后才能让出资源 多线程: 什么是线程(thread)? 线程也是一种多任务编程方式,可以使用计算机的多核资源 线程被称为轻量级的进程 线程的特征: 1.一个进程可以包含多个线程 2.线程是计算机内核使用的最小单位 3.线程也是一个运行过程,也要消耗计算机资源 4.多个线程共享共用进程的资源 5.线程也有自己的特征属性,TID、指令集、线程栈 6.多个线程之间独立运行互不干扰 空间不独立(都消耗进程空间) 7.线程的创建删除消耗的资源要小于进程 线程/进程(1/20) 线程通信: 多个线程共用线程空间,所以进程的全局变量对进程内线程均可见 线程的通信方法就是使用去全局变量通信 注: 线程间使用全局变量进程通信时,全局变量为共享资源 往往需要同步互斥机制 进程和线程的区别和联系: 1.两者都是多任务编程的方式 都能够使用计算机的多核 2.进程的创建和删除要比线程消耗更多的计算机资源 3.进程空间独立,数据安全性好,有专门的进程间的通信方法 4.线程使用全局变量,更加简单,但需要同步互斥操作 5.一个进程可以包含多个线程,线程共享进程空间资源 6.进程线程都独立执行,有自己的特有属性 使用情况: 1.一个进程中并发任务比较多,比较简单,适合使用多线程 2.如果数据程序比较复杂,特别是可能多个任务通信比较多的时候 要考虑使用线程同步互斥的复杂性 3.多个任务存在明显差异,和功能分离的时候没有必要一定写入到一个进程中 4.使用Python要考虑到GIL的问题 Pyhthon线程GIL问题: GIL (全局解释器锁) Python —>支持线程操作—>出现IO同步互斥—>加锁—>超级锁,给解释器加锁 后果: 同一时刻一个解释器只解释一个线程 此时其他线程需要等待。大大降低了Python线程的执行效率 只能实现并发不能实现并行 Python GIL问题解决方案: 1.修改c解释器 2.尽量使用多进程进行并行操作 3.Python线程尽量用在高延迟多阻塞的IO情形 3.不使用CPython 使用C#、JAVA 做的得解释器 网络服务器基础: 循环服务器:: 单进程程序,循环接受客户请求,处理请求,处理完毕后再接受下一次请求 特点: 每次只能处理一个客户端请求,如果客户端长期占有服务器则无法处理其他客户端 请求 优点: 实现简单,占用资源少 缺点: 无法同时处理多个客户端,体验差 使用情况: 任务短暂,可以快速完成,udp比tcp更适合循环 并发服务器: 能够同时处理多个客户端任务请求 IO并发: IO多路复用 协程 优点: 可以实现IO并发操作,占用系统资源少 缺点: 不能够监控CPU密集的情况,并不能有长期阻塞 多进程/线程并发: 为每个客户端单独提供一个进程或线程,处理客户端请求 优点: 客户端可以长期占有服务器 缺点: 消耗计算机资源比较多