udp协议的交互模式服务端不需要考虑客户端是否退出,你发多少那么他就会按照你发的东西直接去传输给客户端不存在黏包现象
服务端:
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(('127.0.0.1',8080))
while True:
msg,address = server.recvfrom(1024)
print('msg>>>:%s'% msg.decode('utf-8'))
print(f'address>>>:{address}')
res = input('请输入您需要输入的内容')
server.sendto(res.encode('utf-8'),address)
客户端:
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
server_address = ('127.0.0.1',8080)
while True:
res = input('请输入您需要输入的内容')
client.sendto(res.encode('utf-8'),server_address)
msg,address = client.recvfrom(1024)
print('msg>>>:%s'%msg.decode('utf-8'))
print(f'address>>>:{address}')
五大核心硬件
计算器,运算器,存储器,输入设备,输出设备
三大核心硬件
cpu,内存,外存(硬盘)
穿孔卡带:cup利用率极低
练级批处理系统:稍微提升cpu利用率但是还是很低
脱机批处理系统:又提升了一些利用率,是现代计算的雏形
io模式:其实就是进程进入输入,输出,程序睡眠,读取文件和保存文件的过程就是进入了io模式
单道技术:当A程序在执行的时候遇到io状态就会停下来等待,直到执行完程序才会继续往下走,执行程序B这种情况叫做单道技术
多道技术:当A程序进入io状态程序会自动跳向程序B开始执行程序B的内容,这种情况叫做多道技术
什么是进程:
进程:其实就是我们的代码在被运行,这个代码就被叫做进程态
程序:当我们代码就是一堆数据并没有被运行的情况那么我们就可以叫他是一个程序或者是死代码
进程的调度
先来先去算法:其实就是我这个进程先开始运行那么就全力运行它直到程序结束开始运行下一个,这种的运行对短运行时间的程序不太友好
短作业有限算法:就是运行速度快的程序优先运行,慢的延后,这种运行对那种运行时间长的程序非常不友好
时间片轮转法和多级反馈队列:将时间平均分配给所有的程序,然后同时运行,如果一段时间这个程序没有被运行完那么就会给她更多的时间片,但是时间片越多那么这个程序的优先级则越低。
并行:并行其实就是多个cpu同时运行多个程序那么我们就叫这种情况为并行
并发:并发其实就是多个进程运行起来看起来像是同时执行的情况我们叫做并发,并行有时候我们也可以叫做并发
就绪态:当我们进程只要开始执行那么他就绝对会先进入就绪态
阻塞态:当我们的程序遇到io操作的时候那么就会进入阻塞态,当阻塞态完成io那么就会重新进入就绪态
运行态:就是完完整整的运行完这个程序那么就会叫做运行态
同步:其实就是程序进行运行的时候进入io状态cpu就会停下等待直到程序结束才会进入下一个进程那么这种情况我们就叫做同步
异步:当我们的程序进入io的话那么我们的cpu就会直接进入其他的程序先运行其他的程序做到不停的情况那么我们就可以称他为异步操作
阻塞态:其实就是程序进入io状态,那么我们就叫它为阻塞
非阻塞:程序没有进入io的状态那么我们就叫他为非阻塞
同步阻塞:最慢的运行一旦遇到io就会停下等待
同步非阻塞:不会进入io状态因为没有
异步阻塞;遇到阻塞就会跳到别的地方执行
异步非阻塞:执行最快
其实就是调用模块利用函数创建多进程
from multiprocessing import Process
import time
def task(name):
print(f'子进程{name}正在运行')
time.sleep(3)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p = Process(target=task, args=('joseph',)) # 创建一个进程对象
p.start() # 开始子进程执行
print('主进程执行')
调用模块利用类的方式执行多进程
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(f'子进程{self.name}正在运行')
time.sleep(3)
print(f'子进程{self.name}执行完毕')
if __name__ == '__main__':
obj = MyProcess('joseph')
obj.start()
print('正在执行主进程')
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p1.start() # 开始执行子进程
p1.join() # 主进程等待子进程结束后再运行
print('主进程') # 最后执行
其实就是让我们的主进程在子进程结束后然后再继续执行的方法
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p2 = Process(target=task, args=('alice', 2))
p3 = Process(target=task, args=('trump', 5))
start_time = time.time()
p1.start() # 开始执行子进程
p1.join() # 主进程等待子进程结束后再运行
p2.start()
p2.join()
p3.start()
p3.join()
end_time = time.time() - start_time
print(end_time)
print('主进程')
# 如果等待它一次执行那么执行时间就会很长,8.649637937545776
from multiprocessing import Process
import time
def task(name, n):
print(f'子进程{name}正在执行')
time.sleep(n)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p1 = Process(target=task, args=('joseph', 1)) # args通过元组的形式给函数传参
p2 = Process(target=task, args=('alice', 2))
p3 = Process(target=task, args=('trump', 5))
start_time = time.time()
p1.start() # 开始执行子进程
p2.start()
p3.start()
p1.join() # 主进程等待子进程结束后再运行
p2.join()
p3.join()
end_time = time.time() - start_time
print(end_time)
print('主进程') # 只要调换下位置让他们先开始执行那么结果就是同时运行进入io态,结束
各进程之间要是想要数据交互那么可能就需要通道进行传输也叫队列
from multiprocessing import Process
count = 999
def task():
global count
count = 666
print('子进程打印的money', count) # 666
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print('主进程', count) # 999
print(count) # 999
其实就是生产者只和缓冲区进行交互,而消费者也只和缓冲区进行交互,有缓冲区来协调两者的平衡关系不能两者直接进行交互,然后要是内部东西没有了那么就需要生产者进行补充吗,然后消费者才能购买
from mlutprocessing import Queue
q = Queue (3) # 这个数字是路i当以的我们可以设置一共可以产生多少个队列的阀值
q.put() # 向队列中增加值
p.pull() # 查看队列是否已经存满
q.get() # 从队列中进行取值
q.empty() # 查看队列是否已经被取空
q.get_nowait() # 取值 如果没有可以取的值那么就会直接报错
p.terminate() # 销毁该进程
p.is_alive() # 查看该进程是否还存活
current_process().pid # 查看进程号
os.getpid # 查看进程号
os.getppid # 查看父进程号
子进程和父进程进行数据交互
from multiprocessing import Queue, Process
def procedure(q):
q.put('子进程procedure往列队中添加了数据')
def consumer(q):
print('子进程consumer往列队中添加了数据', q.get())
if __name__ == '__main__':
q = Queue()
# q.put('主进程向对列中添加了新的数据')
p1 = Process(target=procedure, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start() # 子进程consumer往列队中添加了数据
# 子进程procedure往列队中添加了数据主进程执行
p1.join()
p2.start()
p2.join()
print('主进程执行')
其实就是我们可以定义这个进程守护另一个进程只要被守护进程结束那么该进程就会直接结束
from multiprocessing import Process
import time
def task(name):
print(f'子进程{name}正在运行')
time.sleep(3)
print(f'子进程{name}执行完毕')
if __name__ == '__main__':
p = Process(target=task, args=('joseph',)) # 创建一个进程对象
p.daemon = True # 将子进程设置成父进程的守护进程,只要父进程一结束那么就立即结束
p.start() # 开始子进程执行
# p.join()
print('主进程执行')
僵尸进程其实就是我们的子进程结束没有返回值或者返回了但是父进程没有接收到然后导致父进程无法正常关闭那么就会产生一个僵尸进程,僵尸进程危害电脑的运行所有要尽量避免有僵尸进程
孤儿进程:其实就是父进程意外暴毙,没有父进程接收返回值那么这个进程就会变成一个孤儿进程,但是我们有一个进程福利院来接收这样的孤儿进程叫做init
互斥锁其实就是将并发变成串行的一种锁,使进程数据不会错乱
from multiprocessing import Process,Lock
import time
import json
import random
def search(name):
with open(r'data.json','r',encoding='utf-8')as f:
data = json.load(f)
print('%s正在查票,当前余票为:%s'% (name,data.get('ticket_num')))
def buy(name):
with open(r'data.json','r',encoding='utf-8')as f:
data = json.load(f)
time.sleep(random.randint(1,5))
if data.get('ticket_num') > 0:
data['ticket_num'] -= 1
with open(r'data.json','w',encoding='utf-8')as f:
json.dump(data,f)
print('%s成功购买前往理想乡的车票'% name)
else:
print('%s很遗憾买不到票,今晚都睡不着了'% name)
def run(name,mutex):
search(name)
mutex.acquire() # 枪锁
buy(name)
mutex.release() # 施放锁
if __name__ == '__main__':
mutex = Lock()
l1 = ['joseph','Alice','Trump','Jason']
for i in l1:
p = Process(target=run,args=('用户名%s'% i,mutex))
p.start()
进程:进程是资源单位,负责在内部拿去相应的所有资料就像是一个工厂
线程:就相当于车间中的流水线,只需要拿取自己的数据即可然后就可以运行
进程下至少拥有一条线程,如果没有那么他就没有存在的必要
还是和创建进程以一样一种是以函数来创建而另一种则是类的方法
方式一:
from threading import Thread
import time
def task(name):
print(f'{name}正在执行')
time.sleep(3)
print(f'{name}执行结束')
t = Thread(target=task,args=('joseph',))
t.start() # 两个都可以执行,但是最好写上下方的启动代码,以增加兼容性和规范性
print('主线程')
if __name__ == '__main__':
t = Thread(target=task, args=('joseph',))
t.start()
print('主线程')
"""
开设线程不需要完整的拷贝代码,所以无论什么系统都不会出现反复草早的情况,也不需要像启动进程时一样使用启动脚本,但是为了兼容性和规范性我们最好也写上启动脚本
"""
方式二:
from threading import Thread
import time
class MyThred(Thread):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print(f'{self.name}正在执行')
time.sleep(3)
print(f'{self.name}执行结束')
obj = MyThred('jsoeph')
obj.start()
print('主线程')
和进程一样就是当使用join的子进程结束后那么父进程才会继续运行
from threading import Thread
import time
def task(name):
print(f'{name}正在执行')
time.sleep(3)
print(f'{name}执行结束')
if __name__ == '__main__':
t = Thread(target=task, args=('joseph',))
t.start()
t.join()
print('主线程')
在进程中我们的多进程之间并不能直接数据交互必须要有通道和队列才可以进行数据交互,然而在进程与进程之间就可以做到数据自由交互,子进程和父进程之间可以进程数据交互
from threading import Thread
count = 999
def func():
global count
count = 666
t = Thread(target=func)
t.start()
t.join()
print(count) # 666
1.进程号
在同一个进程下的多个线程都拥有同一个进程的进程号
2.线程名
from threading import Thread,current_thread
from threading import Thread
count = 999
def func():
global count
count = 666
print(current_thread().name) # Thread-1
t = Thread(target=func)
t.start()
t.join()
print(current_thread().name) # MainThread
print(count) # 666
3.进程下的线程数
active_count()
守护线程其实就是和守护进程一样都是,都是被守护线程一旦结束那么守护他的线程就会跟着直接结束
from threading import Thread
import time
def task():
print('子进程运行task函数')
time.sleep(3)
print('子进程运行task函数结束')
t = Thread(target=task)
t.daemon = True
t.start()
print('主进程')
本质上也是一种互斥锁,但是是一款在Cpython中自带的一种全局解释器锁,在全局解释器锁的情况下将并发变成串行依次运行使数据不会被垃圾回收机制所回收掉
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
from threading import Thread
count = 100
def task():
global count
count -= 1
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 0
在数据中存在io的情况下那么就会变成并发状态那么我们的GIL就不能触发,所以就会导致数据错乱的风险那么这种时候就需要我们自己去给她加锁
from threading import Thread
import time
count = 100
def task():
global count
num = count
time.sleep(0.1)
count = num - 1
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 99
"""
自己给自己加锁来完成统计
"""
from threading import Thread,Lock
import time
count = 100
mutex = Lock()
def task():
mutex.acquire()
global count
num = count
time.sleep(0.1)
count = num - 1
mutex.release()
t1_list = []
if __name__ == '__main__':
for i in range(100):
t = Thread(target=task)
t.start()
t1_list.append(t)
for t in t1_list:
t.join()
print(t1_list)
print(count) # 0
多种验证方法
单cpu
多cpu
单CPU操作
1.io密集型的多进程
需要在内存中多次申请额外的内存空间,需要消耗更多的时间和资源
2.io密集型的多线程
只需要在进程中申请自己所需要的代码即可,只需要通过多道的技术那么就可以实现多线程操作,消耗的资源和时间较少
3.计算密集型的多进程
同样需要在内存中申请额外的内存空间,然后消耗更多的时间和资源(总计算耗时和申请内存空间的时间,拷贝代码的时间再加上各个进程之间切换的时间)
4.计算密集型的多线程
只需要在进程中申请自己所需要的代码即可,并且通过多道技术直接执行(总计算消耗的时间和切换到各线程的时间)
5.总结
所以说在单cup中python的多线程还是非常有用的,即节省内存空间又速度较快
1.io密集型的多进程
总耗时(单个进程的耗时+IO操作的耗时+申请内存空间的耗时+拷贝代码的耗时)
2.io密集型的多线程
总耗时(单个线程的耗时+IO操作的耗时)
3.计算密集型的多进程
总耗时(单个进程的耗时)
4.计算密集型的多线程
总耗时(多个进程的耗时总和,但是由于内部有优化代码,所以实际上没有那么长的时间进行计算)
5.总结
在多CUP进行密集型计算时由于多进程可以有多个核进行计算所以计算时间会非常短所以在多CPU多计算模型的情况下多进程占据主要又是,也可以称之为完胜,而多线程因为没有办法享用多cpu的好处所以只能一个CPU慢慢计算。
多CPU代码展示
1.小知识使用代码查看自己电脑是几核处理
import os
print(os.cpu_count()) # 12
2.展示多计算状态的运行
from threading import Thread
from multiprocessing import Process
import os
import time
def work():
res = 1
for i in range(1,100000):
res *= i
if name == 'main':
start_time = time.time()
p_list = []
for i in range(12):
p = Process(target=work)
p.start()
p_list.append(p)
for p in p_list:
p.join()
print('总耗时:%s'%(time.time() - start_time)) # 总耗时:5.136746883392334
if name == 'main':
start_time = time.time()
t_list = []
for i in range(12):
t = Thread(target=work)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print('总耗时:%s' % (time.time() - start_time)) # 总耗时:27.33429765701294
其实就是在线程中,两个并发的线程都拿到了对方需要拿的锁那么就会形成死锁状态
from threading import Thread,Lock
import time
mutexA = Lock()
mutexB = Lock()
class MyThread(Thread):
def run(self):
self.func1()
self.func2()
def func1(self):
mutexA.acquire()
print(f'子进程{self.name}获取A锁')
time.sleep(3)
mutexB.acquire()
print(f'子进程{self.name}获取B锁')
mutexB.release()
print(f'子进程{self.name}获取B锁')
mutexA.release()
print(f'子进程{self.name}获取A锁')
def func2(self):
mutexB.acquire()
print(f'子进程{self.name}获取B锁')
time.sleep(3)
mutexA.acquire()
print(f'子进程{self.name}获取A锁')
mutexA.release()
print(f'子进程{self.name}获取A锁')
mutexB.release()
print(f'子进程{self.name}获取B锁')
for i in range(10):
t = Thread()
t.start()
信号量其实就是我们可以限定可以产生多少把锁
from threading import Thread,Semaphore
import time
import random
SP = Semaphore(3) # 设置信号量为3也就是三把锁
class MyThread(Thread):
def run(self):
SP.acquire()
print(self.name)
time.sleep(random.randint(1,3))
SP.release()
for i in range(20):
t = MyThread()
t.start()
event就像是等红绿灯只有在被等待程序执行到的时候那么等待程序才会执行
from threading import Thread,Event
import time
import random
event = Event()
def light():
print('比赛准备开始,本场次有黑哨请所有人启动赛车听到自己的指令出发')
time.sleep(random.randint(1,5))
print('预备,鸣发动机,let GO!GO!GO!')
event.set() # 发送指令
def car(name):
print(f'{name}正在启动赛车')
event.wait() # 等待指令
print(f'{name}发动机轰鸣后出发了')
t = Thread(target=light)
t.start()
l1 = ['Joseph','Alice','Trump','kdi','jason']
for i in l1:
t = Thread(target=car,args=(f'选手{i}',))
t.start()
在我们呢的进程和线程中既然我们做服务的时候可以产生很多的进程和线程同时运行也就是并发的结果,但是由于我们的硬件跟不上我们创建的应用过程所以受到硬件水平的限制我们必须要设置一共可以产生多少个进程和线程来限制产生
"""
进程池和线程池本质上就是帮它定了一个阀值,让他只能在这个阀值内运行多了那么对不起,你等着吧
"""
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor
from threading import current_thread
import os
import time
pool1 = ProcessPoolExecutor(3)
pool2 = ThreadPoolExecutor(3)
def task(n):
print(current_thread().name)
print(os.getpid())
print(os.getppid())
print(n)
time.sleep(1)
return '会返回什么呢'
def func(args,*kwargs):
print('func',args,kwargs)
print(args[0].result())
if name == 'main':
for i in range(5):
res = pool1.submit(task,123)
print(res.result())
pool1.submit(task,123).add_done_callback(func)
if name == 'main':
for i in range(5):
res = pool2.submit(task,123)
print(res.result())
pool2.submit(task,123).add_done_callback(func)
pool2.submit(task,123).add_done_callback(func)
进程:资源单位
线程:执行单位
协程:单个线程的并发
携程:一款旅行软件,住酒店看携程
协程在单线程下帮助我们的代码实现并发,帮我们在到io状态的时候立即捕获然后让cpu去执行别的欺骗cpu一直跑
from gevent import monkey;monkey.patch_all() # 就是这样写的,我也不知道为什么(猴子补丁)
from gevent import spawn
import time
def func1():
print('func1 正在执行')
time.sleep(3)
print('func1 执行完毕')
def func2():
print('func2 正在执行')
time.sleep(6)
print('func2 执行完毕')
if name == 'main':
start_time = time.time()
# func1()
# func2() # 9.022636413574219
s1 = spawn(func1) # 一旦遇到io操作那么就立即跳到别的地方执行,如果都在io那么久反复横跳
s2 = spawn(func2) # # 6.01244044303894
s1.join()
s2.join()
print(time.time() - start_time)
1.服务端
import socket
from gevent import monkey;monkey.patch_all()
from gevent import spawn
def communication(sock):
while True:
data = sock.recv(1024)
print(data.decode('utf-8'))
sock.send(data.upper())
def get_server():
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
sock,address = server.accept()
spawn(communication,sock)
s1 = spawn(get_server)
s1.join()
2.客户端
import socket
from threading import Thread,current_thread
def get_client():
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
client.send(f'good night {current_thread().name}'.encode('utf-8'))
data = client.recv(1024)
print(data.decode('utf-8'))
for i in range(20):
t = Thread(target=get_client)
t.start()
起源······文本文件
发展······软件开发目录规范
现阶段·····数据库服务
单机模式
联机交互模式
远程数据库
数据库的表达角度
数据库的本质
关系型数据库
id
name
password
1
joseph
123
2
jason
520
SQL
形态
介绍
MySQL
开源
使用最为广泛,数据库学习必学,现在安全程度也变得越来越高
PsotgreSQL
开源
支持二次开发
MariaDB
开源
与MySQL是同一个作者,用法也极其相似,名称是以自己女儿名字命名
Oracle
收费
安全性极高,各大银行和重要机关使用
sqlite
小型数据库
主要是用于本地测试在django中自带的一个数据库
db2
开源
转为中型和大型商业机构设计开发
sql server
开源
使用集成的商业智能(BI)工具提供了企业级的数据管理
非关系型数据库
数据结构没有明确的表的形式去表述,一般是以字典的K:V键值对的形式去组织存储
{'name':'jsoeph'}{'username':'Alice','password':'520'}
数据之间无法直接建立数据库层面的关系
SQL
形态
介绍
redis
目前来说最火的非关系数据库
使用频率最好的缓存型数据库
mongoDB
稳定型数据库
最像是关系型数据库的非关系数据库,有Java那味了
memcache
GG
GG
前言
版本
下载及其安装详情
重要文件介绍
bin文件夹
data文件夹
my-default.ini
先启动服务器
查找MySQL文件位置
再次打开新的cmd窗口
用户登录
退出
添加环境变量
讲MySQL服务端设置成自动启动
关闭服务器和移除系统服务
修改密码
mysqladmin命令
通用命令:
mysqladmin -u用户名 -p原密码 password 新密码
第一次修改
mysqladmin -uroot -p(这里为空就好因为默认密码为空,如果安装时你已经设置密码那么直接输你密码即可) password xxx
低版本修改简便方式: # 但是需要先登录
set password=PASSWORD(新密码)即可
忘记密码
把系统内存储你密码的那三个文件删除然后让你朋友将他的三个文件发你粘贴到那三个文件的地址上你用他的账号密码登录,然后你再更改
先关闭服务器,然后就不需要校验用户身份及逆行启动,再去修改安装正常方式启动
1.net stop mysql
2.mysqld --skip-grant-tabes
3.mysql -uroot -p
4.update mysql.user set password=password(xxx) where HOST='localhost' and User='root'
5.net stop mysql
6.net start mysql
兼容性
由于数据库是为了支持各种语言充当客户端,但是各种语言的区别有很大为了解决这个问题我们就像如何做到让所有的语言都可以使用我们的数据库那么就出现了两种方式
语法区别
数据库
操作
作用
帮助理解
库
show databases;
查看所有的数据库
文件夹
表
show tables;
查看所有的表
文件夹中的文件
记录
select * from mysql.user;
查看user表中的所有记录
文件中的数据
符号
作用
;(分号)
SQL语句中的结束符
\c
取消SQL语句执行
操作
代码
作用
增
create database 库名;
增加一个新的库
查
show databases; |show create database 库名;
查询这个库下的数据
该
alter database 库名 charset='gbk';
更改这个库下的数据
删
drop database 库名;
删除这个库
查看所在库名
select database(库名); use 库名;
如果没有的话默认为NULL
操作
代码
作用
增
create table 表名(字段名 字段类型)
增加表内数据
查
show tables;|show create table 表名; |descrlbe 表名;|desc 表名;
查看表内的内容
改
alter table 旧表名 rename 新表名;
改表名
删
drop table 表名;
删除表
操作
代码
作用
增
insert into 表名 values(数据,数据); |insert into 表名 values(数据,数据);
增加表内的数据
查
select * from 表名; |select 字段1,字段2 from 表名;
查看表内的所有字段
改
updata 表名 set 字段名=新数据 where 筛选条件;
修改表内的数据
删
defete from 表名;|defete from 表名 where 筛选条件;
删除表中所有数据和按条件删除数据
手机扫一扫
移动阅读更方便
你可能感兴趣的文章