一、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的计算机
三、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服务,再命令行中重启服务器验证新密码