一、epoll
开头提示: epoll仅在linux中可用 由于select 只能同时处理1024个客户端,若还有更多的客户端,就没法处理,
因此linux中提供了epoll 这种多路复用的IO模型,注意其他平台没有相应的
实现。 select与epoll的区别: select实现: 1.先将所有socket放到一个列表中rlist=[socket1,socket2,...] 2.遍历这个列表将进程A 添加到每个socket的等待队列中 然后阻塞进程 3.当数据到达时,cpu执行中断程序将数据copy给socket 同时唤醒处于等待
队列中的进程A 为了防止重复添加等待队列 还需要移除已经存在的进程A 4.进程A唤醒后 由于不清楚那个socket有数据,所以需要遍历一遍所有socket
列表 select的缺点: 1.select需要遍历socket列表,频繁的对等待队列进行添加移除操作 2.数据到达后还需要给遍历所有socket才能获知哪些socket有数据 这两个操作消耗的时间随着要监控的socket的数量增加而大大增加,出于
效率考虑才规定了最大只能监视1024个socket
epoll实现: epoll解决的问题: 1.避免频繁的对等待队列进行操作 2.避免遍历所有socket 在epoll中,解决第一个问题: import socket,select server = socket.socket() server.bind(("127.0.0.1",1688)) server.listen(5) #创建epoll事件对象,后续要监控的事件添加到其中 epoll = select.epoll() #注册服务器监听fd到等待读事件集合 epoll.register(server.fileno(), select.EPOLLIN) # 需要关
注 server这个socket的可读事件 # 等待事件发生 while True: for sock,event in epoll.poll(): pass 在epoll中epoll.poll则用于阻塞进程register 与 unregister函数用于
维护等待队列 register是进程添加到等待队列中 unregister 把进程从等待队列中删除 使用这两个函数我们自己来控制等待队列的添加和删除 从而避免频繁操作等待
队列
第二个问题是select中进程无法获知哪些socket是有数据的所以需要遍历 epol为了解决这个问题,在内核中维护了一个就绪列表 1.创建epoll对象,epoll也会对应一个文件,由文件系统管理 2.执行register时,将epoll对象 添加到socket的等待队列中 3.数据到达后,CPU执行中断程序,将数据copy给socket 4.在epoll中,中断程序接下来会执行epoll对象中的回调函数,传入就绪的
socket对象 5.将socket,添加到就绪列表中 6.唤醒epoll等待队列中的进程 进程唤醒后,由于存在就绪列表,所以不需要再遍历socket了,直接处理就绪列
表即可 解决了这两个问题后,并发量得到大幅度提升,最大可同时维护上万级别的socket
epoll代码: #客户端 import socket client=socket.socket() client.connect( ('127.0.0.1',1688)) while True: data =input('input:') if data == "q": break if not data: continue client.send(data.encode("utf-8")) data = client.recv(1024) print ('客户端收到的数据:',data) client.close() #服务器: import select,socket server=socket.socket() server.bind(('127.0.0.1',1688)) server.listen(5) epoll=select.epoll() epoll.register(server.fileno(),select.EPOLLIN) socket_fd={server.fileno():server} msgs=[] while True: for fd,event in epoll.poll(): sock=socket_fd[fd] if sock==server: client,addr=sock.accept() epoll.register(client.fileno(),select.EPOLLIN) socket_fd[client.fileno()]=client elif event==select.EPOLLIN: data=sock.recv(2048) if not data: epoll.unregister(sock.fileno()) del socket_fd[sock.fileno()] sock.close() continue # sock.send(data+b'sd') epoll.modify(sock.fileno(),select.EPOLLOUT) msgs.append((sock,data)) elif event==select.EPOLLOUT: for i in msgs[:]: if i[0]==sock: sock.send(i[1] + b'sd') msgs.remove(i) epoll.modify(sock.fileno(),select.EPOLLIN)
二、数据库相关概念
数据库本质就是一套CS结构的TCP程序,客户端连接到服务器 向服务器发送指令,
来完成数据的操作
数据Data:
述事物的符号记录称为数据,描述事物的符号既可以是数字,也可以是文字、图片,
图像、声音、语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机
数据库DataBase,简称DB:
数据库即存放数据的仓库,只不过这个仓库是在计算机存储设备上,而且数据是按
一定的格式存放的
数据库是长期存放在计算机内、有组织、可共享的数据即可。
数据库中的数据按一定的数据模型组织、描述和储存,具有较小的冗余度、较高
的数据独立性和易扩展性,并可为各种 用户共享
数据库管理系统DataBase Management System 简称DBMS:
科学地组织和存储数据,高效获取和维护数据的一个系统软件
如MySQL、Oracle等
数据库 与 文件系统的对应关系:
数据:本质是文件中某一行的 一部分数据
记录:本质是文件里的一行数据
表 :一个文件
数据库:文件夹
DBMS:数据库管理系统
数据库服务器:运行有DBMS的计算机
数据库的分类
关系型数据库
1. 有约束
2. 基于硬盘的存储 (就是将数据存储到硬盘上, 持久化 === 落地)
典型代表:
MySQL oracle sqlserver(微软) sqllite db2
非关系型数据
1. 没有约束 (key--->value)
2. 基于内存存储 (将数据放入到内存中)
典型代表:
MemCache, redis(微博), mongodb
三、mysql
MySQL:一个关系型数据库管理系统。 #mysql就是一个基于socket编写的C/S架构的软件 #客户端软件 mysql自带:如mysql命令,mysqldump命令等 python模块:如pymysql 安装方式: 1.下载解压包 2.解压到某个目录下 3.添加环境变量 将bin所在的完整路径 copy 添加系统的path中 4.作为服务器 应该自启动mysql服务器 需要制系统服务 mysqld --install 运行输入services 查看是是否成功 删除服务 sc delete mysql 如果需要重装的话... 启动服务 net start mysql 停止服务 net stop mysql
mysql连接服务器: 本质是TCP程序,必须指定ip和端口 ,如果服务器就运行在本机上 可以省略ip
如果端口没改过 也可以省略端口 mysql -hip -P端口 -u用户名 -p密码 实例: mysql -uroot -p mysql 5.6 默认是没有密码的 修改管理员密码: 1.如果知道原始密码 可以使用mysqladmin 这个工具 mysqladmin -p旧密码 -u用户名 password 新密码 实例: mysqladmin -uroot -p password 123 2.不知道原始密码的情况:跳过授权表 我们可以在启动服务器时
指定让其忽略授权信息 1.先管理员 停止服务 net stop mysql 执行 mysqld --skip-grant-tables 2.然后打开另一个cmd,执行下面代码: 无密码登录root账户 mysql -uroot -p 3.执行更新语句 update mysql.user set password = password("123")
where user="root" and host = "localhost"; 4.刷新权限 flush privileges; 5.先开启mysql服务,再命令行中重启服务器验证新密码