Day10 并发编程&数据库基础

1 内容回顾

# 网络编程# 1.概念# osi五层协议# 应用层# 传输层# tcp 面向连接通信,并且数据之间无边界,可靠# 先建立连接 : 三次握手# 基于连接通信 :每一条信息都有回执# 粘包现象# struct模块自定义协议解决# 断开连接 :  四次挥手# udp 不需要提前建立链接,数据之间有边界,不可靠-# 不需要建立\断开连接# 只要知道对方的ip和端口直接发送信息就可以# 网络层# 数据链路层# 物理层# 2.代码# socket# osi5层协议除了应用层之外其他基层的抽象层# tcp-server
import socket
sk = socket.socket()
sk.bind(('192.168.12.1',9001))
sk.listen()conn,addr = sk.accept()   # 接受客户端请求建立连接 -- 三次握手
conn.send(msg)     # msg必须是字节类型
message = conn.recv(n)    # n是接受消息的最大字节数
conn.close()       # 关闭了和某一个客户端的连接 -- 四次挥手sk.close()         # 关闭了整个网络服务# tcp-client-+
import socket
sk = socket.socket()
sk.connect(('192.168.12.1',9001))  #  三次握手
message = sk.recv(n)
sk.send(msg)
sk.close()# udp-server
import socket
socket.socket(type = socket.SOCK_DGRAM)from socket import socket,SOCK_DGRAM
sk = socket(type=SOCK_DGRAM)
sk.bind(('127.0.0.1',9002))msg,client_addr = sk.recvfrom(n)
sk.sendto(消息,client_addr)sk.close()# udp-client
import socket
sk = socket.socket(type = socket.SOCK_DGRAM)
sk.sendto(msg,('127.0.0.1',9002))
msg,server_addr = sk.recvfrom(n)
sk.close()# socketserver
import socketserverclass Myserver(socketserver.BaseRequestHandler):def handle(self):conn = self.requestserver = socketserver.ThreadingTCPServer(Myserver,('127.0.0.1',9000))
server.serve_forever()

2 今日内容

# 并发编程# 概念 : 面试\未来做架构相关也会用# 有少量的代码# 并发的概念# 进程# 线程 : GIL锁 由操作系统控制 对于IO的感知能力非常强# 协程 : 由程序控制的 对于IO操作的敏感度相对低 只有和网络相关的阻塞能够被协程感知到
# mysql数据库# 程序员对数据库的基础操作# 只要有io,程序就会阻塞

3 并发编程

# input :# recv recvfrom input read load
# output:# send sendto print write dump
# 输入输出是不占用CPU的
# 计算机是多少cpu : 4c 8c 16c
# 纯计算 :就是不涉及任何输入输出,单纯对内存中数据进行操作
# 只要涉及到输入输出都要占一大笔时间# 7200r : 7200转每分钟# 从硬盘上找到一个数据的时间 0.9ms = 0.0009s# 0.3s
# CPU指令的计算速度 500000000 = 5亿 每一秒钟可以执行5亿条指令
# 50000 * 9s = 45w
# 读一次硬盘的时间够CPU执行45w条指令了# pycharm qq EV录屏 浏览器 飞秋 360 vnc 搜狗输入法
# n多程序同时工作在计算机中,这些程序都需要CPU处理# 1.CPU如何为超过本身个数的服务们提供服务# 2.服务于服务之间是怎么分配的内存
# 所有的程序在没执行起来之前叫程序\文件,执行起来之后叫进程
# 什么叫做进程process? 进行中的程序
# 每一个进程在运行的过程中会被分配一块属于他自己的内存,进程之间的内存隔离
# CPU在多个进程之间进行轮转执行进程的任务
# 如果两个进程在CPU上同时被执行 -- 并行
# 如果两个进程看起来是同时执行的,但实际上在一块儿CPU上轮流被执行 -- 并发# 进程 : 内存的隔离
# 线程 : 具体代码的执行进度
# 协程

4 程序

import os
import time
from multiprocessing import Process
def func1():print(123,os.getpid())time.sleep(1)print(456)def func2():print('aaa',os.getpid())time.sleep(1)print('bbb')
if __name__ == '__main__':Process(target=func1).start()Process(target=func2).start()# func1()
# func2()

5 进程

# 进程是计算机中资源分配的最小单位
# 所有的计算机中的内存资源 文件资源 程序代码# 进程可以被操作系统调度\CPU执行
# 一个进程在创建的时候 必须创建大量的资源内存资源 文件资源 程序代码
# 一个进程在结束的时候 必须被销毁
# 谁来销毁这个进程呢?# 一个进程总是被他的父进程销毁掉
# 进程与进程之间有一个父子关系# 父进程要负责销毁子进程
# 你在你写的python代码中开启的所有进程都是子进程
# 而你写的这个程序本身是这些子进程的父进程import os
import time
from multiprocessing import Processdef func(参数1,参数2):print('一个子进程',os.getpid(),参数1,参数2)time.sleep(1)if __name__ == '__main__':   # 当本文件被导入的时候不执行if条件中的代码p = Process(target=func,args=(1,2))p.start()p.join()   # 阻塞 等待子进程执行完毕print('子进程执行完啦')import socket
from multiprocessing import Process
def func(conn):while True:conn.send(b'hello')     # msg必须是字节类型message = conn.recv(1024)    # n是接受消息的最大字节数print(message)if __name__ == '__main__':sk = socket.socket()sk.bind(('127.0.0.1',9001))sk.listen()while True:conn,addr = sk.accept()   # 接受客户端请求建立连接 -- 三次握手Process(target=func,args=(conn,)).start()conn.close()

6 线程

# 创建一个进程是非常浪费时间 和 资源的
# 线程 -- 轻型进程
# 同一个进程之间的多个线程内存是共享的
# 线程的开启速度比进程快
# 线程也可以利用多核# 正常的进程和线程之间的区别 :# 进程是 内存隔离的 占用的资源多# 线程之间 内存共享的 占用的资源少# python的线程# cpython解释器下的多线程# 同一个进程下的多个线程不能被CPU同时执行# 多个线程中的IO操作仍然会被规避
# 大部分只要涉及到文件\网络的操作,多线程会更快
# 真正能够参与计算的不过就是那几个CPU# 规避IO操作,让IO操作的时间尽量的缩短# 或者尽量的复用这部分时间
import time
from urllib import request
from threading import Thread
url_lst = ['http://www.baidu.com','http://www.sogou.com','http://www.qq.com','http://www.163.com','http://www.taobao.com','http://www.jd.com','http://www.tmall.com','http://www.cnblogs.com','http://www.mi.com','http://www.luffycity.com',
]
def get_url(url):ret = request.urlopen(url)  # 请求一个网页start_t = time.time()
t_lst = []
for url in url_lst:   # 开启10个线程,每个线程个字去请求1个网页,即同时请求10个网页t = Thread(target=get_url,args=(url,))t.start()t_lst.append(t)
for t in t_lst:t.join()
print(time.time()-start_t)start_t = time.time()
for url in url_lst:ret = request.urlopen(url)
print(time.time()-start_t)# jython Python语言 最终是被JAVA解释器解释的 而java的解释器回收机制不是gc -- 不会受到全局解释器锁的影响
# pypy
# cpython 有一个全局解释器锁 GIL 是由于GC机制和解释型语言双重限制导致了必须要在解释器中加锁# 导致了在一个进程中不能有多个线程同时访问CPU# 虽然不能同时做计算会影响一些效率,但是绝大多部分情况下线程仍然能够非常好的提高程序的效率"""
import socket
from threading import Thread
def func(conn):while True:conn.send(b'hello')     # msg必须是字节类型message = conn.recv(1024)    # n是接受消息的最大字节数print(message)if __name__ == '__main__':sk = socket.socket()sk.bind(('127.0.0.1',9001))sk.listen()while True:conn,addr = sk.accept()   # 接受客户端请求建立连接 -- 三次握手Thread(target=func,args=(conn,)).start()conn.close()
"""

7 协程

from gevent import socket
import gevent   # gevent在识别阻塞之后,会在遇到阻塞的时候自动识别def func(conn):while True:conn.send(b'hello')     # msg必须是字节类型message = conn.recv(1024)    # n是接受消息的最大字节数print(message)if __name__ == '__main__':sk = socket.socket()sk.bind(('127.0.0.1',9001))sk.listen()while True:conn,addr = sk.accept()gevent.spawn(func,conn)   # 开协程conn.close()# 协程的好处 :可以开的个数更多
# 5 * 20 * 500 = 50000

8 数据库

# 安装数据库 server端# 启动数据库# server端# net start mysql 启动服务端# net stop mysql  关闭服务端# mysql客户端# 执行mysql.exe可以启动客户端,连接上server端# mysql> select user();  # 查看当前登录的用户是谁# ;是sql语句的结束符,写任何代码之后都应该自己添加;表示一句指令的结束
# mysql> exit 表示退出客户端# cmd命令行直接输入 mysql -u用户名 -p密码
# mysql -uroot -p123  表示以root用户登录 密码是123
# 设置密码 set password = password('新密码')# mysql(开源 互联网公司) oracle(金融公司 事业单位) sqlserver db2 postgresql sqllite
# mongodb redis memcache hbase
# 名词# DBMS数据库管理系统# DBA数据库管理员# 什么是库 DB# 什么是表 table# 什么是数据 data# 数据库的操作# 创建库 : create database; 数据库的名字# 相当于创建了一个文件夹# 查看库 : show databases;# 使用库 : use py27# 切换到对应的文件夹下# 查看当前库有哪些表 : show tables;# 删除库 : drop database py27;# 数据表的操作# 创建表# 语法 create table 表名(字段名 类型(长度) 约束,字段名 类型(长度) 约束...);# create table score(id int(8),name char(20),num int(4)) charset=utf8;# 修改表# 查看表结构 :# desc score;                更直观# show create table score;   更全面: 查看表的编码 存储引擎# mysql5.6以上版本 默认innodb# 支持事务# 行级锁 表锁 数据修改频繁# 外键约束# 删除表 : drop table 表名;
# 数据的操作# 增# insert into 表名(字段名) values (值);# insert into score(id,name,num) values (1,'alex',0);# insert into score values (2,'wusir',60);# insert into score values (2,'wusir',60),(2,'wusir',60),(2,'wusir',60);# insert into score(name,num) values ('松松',100);# insert into score(name,num) values ('松松',100),('立立',99);# 删# delete from 表名 where 条件;# delete from score where id = 2;# 改# update 表 set 字段名='新的值' where 条件# update score set id=4 where name = '松松'# 查# select * from 表# 类型 和 约束
# 类型# 数字 :# 整型 :长度的约束都是无效的,它能够表示的大小只和它存储的字节数相关# 年龄 : tinyint 1bytes 不算符号最多可以存到255 算上符号127#  smallint 2bytes#  mediumint 3bytes# int 4bytes 2**32  整数# bigint 8字节 2**64# create table t1(age1 tinyint(2),age2 tinyint,age3 tinyint unsigned);# create table t1(age int unsigned);# 浮点型# float(m,n) 单精度# m 表示一共有多少位# n 表示小数部分占其中的多少# float(5,2)# create table t2(salary float(5,2))# double(m,n) 双精度  能够表示的小数点之后的位数更精准# 薪资# 字符串 :# char(255) : 用户名\密码\手机号\身份证号# char(20)定长存储# 存储 'alex                ' 浪费空间# 操作节省时间# varchar(65535) : 评论 微博 微信朋友圈 论坛# varchar(255)变长存储# 存储 'alex4'  节省空间# 更加浪费时间# create table t4(username char(20),password char(32))# 时间 :# datetime 年月日时分秒# 登陆时间# 修改时间# 出生日期# 跑步计时# date 年月日# 注册时间# time 时分秒# timestamp 时间戳4字节 1970-2038-xx-xx# year 年# create table t5(dt datetime,d date,t time,ts timestamp,y year);# create table t6(dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,d date,t time,ts timestamp,y year);# 单选和多选 : 性别 爱好# enum单选和set多选并去重# create table t7(gender enum('男','女'),hobby set('抽烟','喝酒','烫头','洗脚'));# insert into t7 values('男','抽烟')# 约束
# 数据的查询# 单表查询# 连表查询
# html

9 ftp作业

功能实现版本一:

功能实现版本二:

server端

import hashlib
import json
import socket
import socketserverclass Myserver(socketserver.BaseRequestHandler):def handle(self):msg = self.request.recv(1024)str_msg = msg.decode('utf-8')print(str_msg)opt_dic = json.loads(str_msg)print(opt_dic)if opt_dic['operate'] == 'register':# 把密码按照自己的算法进行摘要md5 = hashlib.md5(opt_dic['username'].encode('utf-8'))md5.update(opt_dic['password'].encode('utf-8'))pwd = md5.hexdigest()print('--->', pwd)# 把用户名和密码写在userinfo文件中with open('userinfo', 'a', encoding='utf-8') as f:f.write('{}|{}'.format(opt_dic['username'], pwd))elif opt_dic['operate'] == 'login':# 把密码按照之前的规则进行加密md5 = hashlib.md5(opt_dic['username'].encode('utf-8'))md5.update(opt_dic['password'].encode('utf-8'))pwd = md5.hexdigest()print('--->', pwd)# 和文件中的用户密码进行逐行比对with open('userinfo', encoding='utf-8') as f:for line in f:user, passwd = line.strip().split('|')if opt_dic['username'] == user and pwd == passwd:print('登录成功')breakelse:print('登录失败')sk = socketserver.ThreadingTCPServer(('127.0.0.1', 9000), Myserver)
sk.serve_forever()

客户端

import json
import socketdef login(sk):usr = input('用户名:').strip()pwd = input('密码:').strip()if usr and pwd:d = {'username': usr, 'password': pwd, 'operate': 'login'}str_d = json.dumps(d)sk.send(str_d.encode('utf-8'))def register(sk):usr = input('用户名:')pwd = input('密码:')pwd2 = input('再次确认密码:')if pwd == pwd2: # 发送明文密码到server端才开始加密d = {'username': usr, 'password': pwd, 'operate': 'register'}str_d = json.dumps(d)sk.send(str_d.encode('utf-8'))# 登录/注册
opt_lst = [('登录', login), ('注册', register)]
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))
for index, opt in enumerate(opt_lst, 1):print(index, opt[0])
num = int(input('输入选项序号:'))
func = opt_lst[num - 1][1]
func(sk)

优化后登录版本:

Server

import hashlib
import json
import socket
import socketserverclass Auth:@staticmethoddef get_md5(opt_dic):md5 = hashlib.md5(opt_dic['username'].encode('utf-8'))md5.update(opt_dic['password'].encode('utf-8'))pwd = md5.hexdigest()return pwd@classmethoddef login(cls, opt_dic):# 把密码按照之前的规则进行加密pwd = cls.get_md5(opt_dic)# 和文件中的用户密码进行逐行比对with open('userinfo', encoding='utf-8') as f:for line in f:user, passwd = line.strip().split('|')if opt_dic['username'] == user and pwd == passwd:dic = {'operate': 'login', 'flag': True}breakelse:dic = {'operate': 'login', 'flag': False}return dic@classmethoddef register(cls, opt_dic):# 把密码按照自己的算法进行摘要pwd = cls.get_md5(opt_dic)# 把用户名和密码写在userinfo文件中with open('userinfo', 'a', encoding='utf-8') as f:f.write('{}|{}\n'.format(opt_dic['username'], pwd))dic = {'operate': 'register', 'flag': True}return dicclass Myserver(socketserver.BaseRequestHandler):def mysend(self, dic):str_d = json.dumps(dic)self.request.send(str_d.encode('utf-8'))def handle(self):msg = self.request.recv(1024)str_msg = msg.decode('utf-8')opt_dic = json.loads(str_msg)if hasattr(Auth, opt_dic['operate']):dic = getattr(Auth, opt_dic['operate'])(opt_dic)self.mysend(dic)sk = socketserver.ThreadingTCPServer(('127.0.0.1', 9000), Myserver)
sk.serve_forever()

Client:

import json
import socketdef send_dic(sk, dic):str_d = json.dumps(dic)sk.send(str_d.encode('utf-8'))def recv_dic(sk):str_dic = sk.recv(1024).decode('utf-8')res_dic = json.loads(str_dic)return res_dicdef get_user(opt='login'):d = {}usr = input('用户名:').strip()pwd = input('密码:').strip()if usr and pwd and opt == 'register':pwd2 = input('密码确认:').strip()if pwd == pwd2:d = {'username': usr, 'password': pwd, 'operate': opt}elif usr and pwd:d = {'username': usr, 'password': pwd, 'operate': opt}return ddef login(sk):d = get_user()if d: send_dic(sk, d)res_dic = recv_dic(sk)if res_dic['operate'] == 'login' and res_dic['flag'] == True:print('登录成功')else:print('登录失败')def register(sk):d = get_user('register')if d: send_dic(sk, d)res_dic = recv_dic(sk)if res_dic['operate'] == 'register' and res_dic['flag'] == True:print('注册成功')else:print('注册失败')# 登录/注册
opt_lst = [('登录', login), ('注册', register)]
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))
for index, opt in enumerate(opt_lst, 1):print(index, opt[0])
num = int(input('输入选项序号:'))
func = opt_lst[num - 1][1]
func(sk)

上传下载功能:

day10-并发编程数据库基础相关推荐

  1. 学习笔记:Java 并发编程①_基础知识入门

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 视频下载: ...

  2. Java并发编程实战基础概要

    文章目录 Java并发编程实战基础概要 开篇 多线程问题有啥难点呢? 为啥要学习并发编程? 并发问题的根源是什么? CPU切换线程执导致的原子性问题是如何发生的? 缓存导致的可见性问题是如何发生的? ...

  3. java并发编程:多线程基础

    文章目录 并发编程三要素 并发编程内存模型 多线程 创建线程的三种方式 volatile synchronized 线程池 ThreadPoolExcutor![在这里插入图片描述](https:// ...

  4. java并发编程艺术——基础篇

    这篇文章目的是为了总结一下这段时间看<java并发编程艺术>学到的东西,尝试用自己的话说出来对java多线程的理解和使用. 一.什么是多线程,为什么要用多线程,多线程带来的挑战 多线程定义 ...

  5. 并发编程-多线程基础

    1.引言 推荐书籍 深入理解Java并发编程 Java并发编程 核心知识点 多线程基础知识 同步和异步的概念 线程安全(线程同步)相关 线程通讯 java1.8并发包 线程池原理分析 锁的概念 专题类 ...

  6. JAVA并发编程JUC基础学习(简介)

    2019独角兽企业重金招聘Python工程师标准>>> 之前写过一篇并发编程的简单实例应用,Future快速实现并发编程,可以很快的在自己的项目中应用,但并不系统,之前说过总结一篇( ...

  7. JAVA并发编程的基础

    1.线程简介 什么是线程? 操作系统在运行一个程序时,会为其创建一个进程. 线程是操作系统调度的最小单元,也叫轻量级进程. 在一个进程里可以创建多个线程,这些线程拥有各自的计数器.堆栈和局部变量等属性 ...

  8. 并发编程 进程基础

    操作系统 多道 .分时.实时 同步异步 同步:一件事情完成后再做另一件事 异步:同时做多件事 阻塞和非阻塞 阻塞:recv,accept,recvfrom 会让整个进程进入阻塞队列 非阻塞:进程只会在 ...

  9. 【并发编程】- 基础篇

    文章目录 1. 概览 1.1 这门课讲什么 1.2 为什么学这么课 1.3 课程特色 1.4 预备知识 2. 进程与线程 2.1 进程与线程 2.2 并行与并发 2.3 应用 3. Java 线程 3 ...

最新文章

  1. python二维元组_python中读入二维csv格式的表格方法详解(以元组/列表形式表示)
  2. Windows Server 2008常见的安全设置
  3. 机器学习(MACHINE LEARNING)MATLAB人口增长模型logistic参数确定
  4. golang相关在线学习文档
  5. 高通fastmmi(ffbm)的使用
  6. 【ArrayList:键盘录入多个数据,以 0 结束,并在控制台输出最大值】
  7. C/C++插入数据到Mysql数据库中
  8. An end-to-end TextSpotter with Explicit Alignment and Attention
  9. python中range函数和xrange函数有什么异同?
  10. C++ - extern C用法浅析
  11. matlab2c使用c++实现matlab函数系列教程-mean函数
  12. 我的2015技术学习流水账
  13. 当C++遇上AUTOSAR编码规范,你的安全我来护航
  14. javascript写的日历控件(收藏)
  15. PHP下制作图灵机器人程序
  16. 12.2 关闭DLM 自动收集统计信息 (SCM0)ORA-00600之[ksliwat: bad wait time]
  17. jlinkV8指示灯不亮 usb无法识别的问题
  18. 【人工智能】1024 程序员节最想要的大礼包!
  19. android 2.2 sdk 源码,Ubuntu 10.10 编译Android2.2(froyo)源码 sdk adt
  20. 感动:我奋斗了18年才和你坐在一起喝咖啡(转)

热门文章

  1. 【unity】角色动画的 Has Exit Time是什么?什么时候需要打钩?
  2. 找不到靶机的IP怎么办,教你几步就会了
  3. 架构模式-微内核架构模式
  4. NGUI 3.0.7的新锚点系统设置不好就会造成显示错误的错觉
  5. Python/Numpy之点积叉积内积外积张量积
  6. 数据分析的三个常用方法,数据趋势、数据对比和数据细分的分析介绍
  7. 软件项目管理期末复习--项目过程模型
  8. cmd命令行初始位置修改
  9. 使用WinHex搜索一个进程中的文本图解
  10. winhex使用经验 1