利用CPU的空闲时间去处理其他数据,提高效率
CPU会在程序进入IO和程序长时间占用资源时切换程序执行
切换时会保存当前程序的执行状态,切换回来后基于记录的状态继续执行
程序是存放在硬盘中的代码,而运行起来的程序就是一个进程
进程的调度算法:时间片轮转法+多级反馈队列
每个进程都运行一个固定的时间片,长时间运行的程序会分到更多时间片,但优先级会更低
并行
多个进程同时运行,必须使用多个CPU
并发
多个进程切换运行,看起来是在同时运行,单个CPU可以实现
就绪态:想要进入运行态必须经过就绪态
运行态:程序运行的状态,时间片结束回到就绪态等待下次执行
阻塞态:程序遇到阻塞进入阻塞态,阻塞结束回到就绪态
同步:提交任务后原地等待
异步:提交任务后去做其他事,结果自动返回
阻塞:阻塞态
非阻塞:就绪态与运行态
同步阻塞:程序排队运行,遇到阻塞等待阻塞结束
同步非阻塞:程序排队运行,遇到阻塞去执行其他程序执行
异步阻塞:程序并发运行,遇到阻塞等待阻塞结束
异步非阻塞:程序并发运行,遇到阻塞切换其他程序执行
使主进程等待子进程结束后再继续运行
进程间数据默认隔离,两个程序想要通信需要借助管道或队列
进程间通信:IPC机制(interprocess communication)
可以使用multiprocessing的Queue队列
q = Queue(5):创建队列对象
q.put():往队列添加数据
q.get():从队列取出数据
q.full():判断队列数据是否是满
q.empty():判断队列数据是否为空
q.get_nowait():从队列取出数据,队列为空时报错
current_process().pid:查看进程号
os.pid:查看进程号
os.ppid:查看父进程的进程号
process.terminate():销毁子进程
process.is_alive():查看子进程是否存活
随着被守护进程的结束而结束的进程
process.daemon = True:设置进程为守护进程
僵尸进程:进程已经结束,但是相关资源没有被清空
孤儿进程:父进程意外结束,但子进程正常运行
因为多个进程操作同一个数据可能会产生数据错乱,为了避免这种情况所以使用互斥锁
互斥锁会将并发变成串行,虽然降低了程序执行效率,但是保证了数据安全
mutex = Lock():创建锁对象
mutex.acquire():获取锁
mutex.release():释放锁
线程是进程下的执行单位,线程才是真正执行程序的,所以每一个进程下都至少有一个主线程
和进程相同,等待子线程执行结束后继续运行
current_thread().name:当前线程名
active_count():统计进程下的线程数
随着被守护线程的结束而结束的线程
thread.daemon() = True:设置为守护线程
GIL本质上也是一把互斥锁,限制了多个线程不能够同时运行,主要是因为cpython解释器中垃圾回收机制不是线程安全的
当创建了两把锁,两个不同的进程或线程分别获得其中之一,而都需要获取另一把锁时,就出现了死锁现象
信号量本质也是互斥锁,不过可以一次性创建多把锁
sp = semaphore(5):创建对象
sp.acquire():获取锁
sp.release():释放锁
使子进程/线程之间能够彼此等待
event = Event():创建对象
event.wait():等待信号
event.set():发送信号
提前创建好一定数量的进程或线程,以后不会再新增
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
obj.submit():提交任务
obj.result():获取返回值
obj.submit().add_done_callback(func):异步回调
在单线程下实现并发
程序员自己写的代码,在检测到IO时自动切换代码运行,使CPU不会切换,最大效率执行程序
from gevent import monkey;monkey.patch_all():固定编写,用于检测所有IO操作(猴子补丁)
form gevent import spawn
数据库的底层操作几乎一致,学会一个其他的都可以快速上手
以管理员身份打开cmd窗口
执行命令:mysqld --install
启动服务端
SQL语句的意思是操作关系型数据库的语法
NoSQL语句的意思操作非关系型数据库的语法
SQL有时候也用来表示关系型数据库 NoSQL也用来表示非关系型数据库
新增库:create database 库名;
查询库:show databases 库名;
show create database 库名;
修改库:alter database 库名 charset=‘gbk’;
删除库:drop database 库名;
查看当前所在的库:select database();
切换当前所在的库:use 库名;
新增表: create table 表名(字段名 字段类型,字段名 字段类型);
查询表:show tables 表名;
show create table 表名;
describe 表名;
desk 表名;
修改表:alter table 表名 rename 新表名;
删除表:drop table 表名;
新增记录:insert into 表名 values(数据,数据),(数据,数据)
查询记录:select * from 表名;
select 字段名,字段名 from 表名;
修改记录:update 表名 set 字段名=新数据 where 筛选条件;
删除记录:delete 表名;
delete 表名 where 筛选条件