並發編程網絡編程和數據庫的基礎操作
阿新 • • 發佈:2019-03-14
同步阻塞 存取 p地址 thread item 本質 8.0 proc 針對
第二部分
網絡編程之 osi七層模型和三次握手四次揮手 socket
# by luffycity.com # 概念 # 應用層 http https ssl smtp ftp # 傳輸層 tcp udp 端口信息 四層路由器 四層交換機 # tcp # 可靠的 面向連接的 全雙工的 流式傳輸 效率低 # 三次握手和四次揮手 # 三次握手 # 把圖背下來 syn ack # 四次揮手 # 把圖背下來 fin ack # 黏包 : (自定義協議)先發送數據的長度,再發送數據 # udp 效率高 不可靠 無連接 基於數據包的傳輸 能夠傳輸的數據的長度有限 # 網絡層 ipv4協議192.168.0.1 ipv6協議 ff2312:f5242:12:1:1:1 網關地址 子網掩碼 路由器 三層交換機 # 數據鏈路層 mac地址 arp(通過ip地址找mac地址),rarp(通過mac地址找ip地址) 網卡 交換機 # 物理層 # 1.評論 限制長度 數據庫的carchar(255) # 2.即時聊天的工具 udp # socket # socketserver # 手寫socket # server - tcp import socket # sk = socket.socket() # sk.bind(('127.0.0.1',9000)) # sk.listen() # # # while True表示能夠和多個client通信 # conn,addr = sk.accept() # 建立三次握手的過程 # # while True表示能夠和一個client說多句話 # conn.recv(1024) # conn.send(b'xxx') # conn.close() # sk.close() # 四次揮手中的兩手 # client -tcp # import socket # sk = socket.socket() # sk.connect(('127.0.0.1',9000)) # # sk.send(b'hello') # sk.recv(1024) # sk.close() # 四次揮手中的兩手 # server -udp # import socket # sk = socket.socket(type=socket.SOCK_DGRAM) # sk.bind(('127.0.0.1',9000)) # while True: # msg,cli_addr = sk.recvfrom(1024) # sk.sendto(msg,cli_addr) # sk.close() # clients -udp import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.sendto(b'msg',('127.0.0.1',9000)) msg,_ = sk.recvfrom(1024) print(msg) sk.close()
並發編程
# by luffycity.com # 操作系統 # 異步同步\阻塞非阻塞\並發並行 # 並發和並行 # 並行 能利用多核 同一時刻 有多個任務在CPU上同時執行 # 並發 不能利用多核 同一時間段內 有多個任務在一個CPU上輪流被執行 # 並行 : 多進程 多線程(在其他語言中) # 同步和異步 # 同步 當我執行一個任務 需要等待這個任務的結果才能繼續執行下一個任務 # 異步 當我執行某一個任務 不需要等待這個任務的結果 就可以繼續執行下一個任務 # 阻塞和非阻塞 # 非阻塞 : cpu一直在工作 # 阻塞 : CPU不工作 recv recvfrom accept input sleep # io操作(輸入輸出都是針對內存的,str,bytes) # input : input read recv recvfrom accept connet close # output: write send sendto connet accept close # 同步阻塞 # def func(): # import time # time.sleep(1) # # def func2(): # func() # print(123) # func2() # 同步非阻塞 # def func(): # a = 1 # b= a+1 # return b # def func2(): # func() # print(123) # func2() # 異步阻塞 # import time # import threading # def func(): # time.sleep(1) # t_l = [] # for i in range(10): # t = threading.Thread(target=func) # t.start() # t_l.append(t) # for t in t_l:t.join() # 異步非阻塞 # 我調用一個函數 不等待這個函數的結果 # 並且我能一直利用cpu # 在正常的編程語言中 # 進程 是計算機中最小資源分配單位 # 數據隔離 開銷(開啟 銷毀 切換)大 內存級別數據安全 但是文件操作\數據庫操作數據不安全 # manager : 數據共享 # IPC(inter process communication):隊列\消息隊列memcache\rabbitmq\redis # 管道 : 基於socket + pickle # 原生的queue : 基於文件(管道 + 鎖) # 第三方工具 : 基於網絡\穩定性更強 # 線程 計算機中能被CPU調度的最小單位 # 數據共享 開銷(開啟 銷毀 切換)小 數據不安全 數據共享程序可能會同時去操作一個變量 # 協程 本質是一條線程 協程任務對於操作系統來說不可見 協程是用戶級的單位 # 數據共享 開銷非常小(函數的調用的速度一樣快) 數據絕對安全 # 在Cpython解釋器下 # 進程 # 線程 不能利用多核 (flask django) : 文件操作更快 # GIL鎖 : 全局解釋器鎖,鎖的是線程,保證了同一個進程中的多個線程之間只有一個線程能訪問CPU # 限制了一個python進程中的多線程不能利用多核 # 無法處理高計算型的任務 # 解決方案 開多進程 # 協程(tonado tiwsted sanic scrapy) : 所有的time.sleep socket 協程更快 # 一條線程 # 指的是程序能夠在多個協程任務之間來回切換 # 如果在程序中遇到io就切換去執行另一個程序,實現了使用協程來規避io,提高cpu的使用率 # def func(): # yield 1 # print(123) # yield 2 # def func2(): # g = func() # g.__next__() # asyncio 基於yield關鍵字\gevent 基於greenlet來完成的 # aiohttp # 操作系統中的IO多路復用 # select poll epoll # select windows # poll epoll linux # epoll最好 # 代理,監聽所有的網絡對象,是否有讀\寫事件發生 # import socket # import select # sk = socket.socket() # sk.setblocking(False) # sk.bind(('127.0.0.1',9000)) # sk.listen() # read_l = [sk] # while True: # rl,wl,el = select.select(read_l,[],[]) # 阻塞 # for item in rl: # if item is sk: # conn,addr = sk.accept() # read_l.append(conn) # else: # msg = item.recv(1024) # if msg == b'': # read_l.remove(item) # continue # print(msg) # item.send(b'received') # io多路復用 # 代理所有的網絡對象,幫助我們監聽有哪一個對象發生了註冊事件(讀\寫\異常),然後通知程序,去進行相應的處理 # selectors模塊 # 能夠有效的利用poll和epoll前提是你所在的操作系統是有這兩個機制的 # 自動的識別當前操作系統中我們能用的最好的機制 #服務端 from socket import * import selectors sel=selectors.DefaultSelector() def accept(sk,mask): conn,addr=sk.accept() sel.register(conn,selectors.EVENT_READ,read) def read(conn,mask): try: data=conn.recv(1024) if not data: print('closing',conn) sel.unregister(conn) conn.close() return conn.send(data.upper()+b'_SB') except Exception: print('closing', conn) sel.unregister(conn) conn.close() sk=socket(AF_INET,SOCK_STREAM) sk.bind(('127.0.0.1',8088)) sk.listen(5) sk.setblocking(False) sel.register(sk,selectors.EVENT_READ,accept) #相當於網select的讀列表裏append了一個文件句柄server_fileobj,並且綁定了一個回調函數accept while True: events=sel.select() # 代理在這裏等待,等events事件來,一旦等來了 那麽一定是有新的鏈接 來 或者是有發送給conn的數據來 for sel_obj,mask in events: callback=sel_obj.data #callback=accpet/read callback(sel_obj.fileobj,mask) #accpet(server_fileobj,1) # select 只能使用select # selector 能用select poll epoll # select 采用輪詢,能夠處理的對象的個數有限 # poll 采用輪詢,能夠處理的對象的個數無限的 # epoll 回調 # TCP協議 # 監聽多個sk,conn對象,誰的數據先來,我就通知誰來處理 # 好處是什麽 # 把很個等待變成一個等待,有一個代理替我們來接收所有的請求 # 1.刷一下考試題 # 把所有課上沒有講過答案的 圈出來
數據庫1
# by luffycity.com # 非關系型數據庫 # mongdb 智能玩具 # redis 路飛項目 # kafka 消息中間件 # 關系型數據庫 # oracle # sqllite # mysql # ddl dml dcl # 版本的數據庫 5.6/ 5.7 / 8.0 # 存儲引擎 # innodb 5.6版本以上默認的存儲引擎 # 支持事務 # select + update # begin; # select * from 表 where 條件 for update; # update 表 set 字段=值 where 條件; # commit; # 行級鎖 : # 對於少量數據的並發的修改效率更高 # 但是對於整個表中大量字段的修改鎖反而拖慢了速度 # 支持外鍵 # create table 表名( # 字段名 數據類型(長度) 約束, # uid int, # foreign key uid references user(ui) # on update cascade # ) # myisam 5.5版本以下默認的存儲引擎 # 查詢速度和insert的速度都很快 # 表級鎖 : 對高並發的大量修改沒有優勢的 # innodb支持的都不支持 # memory # 斷電消失 # blakhole # 多級主從復制 往裏寫啥啥沒 # binary_log = bin_log # sql -> 分析 -> 優化 -> 編譯 -> 二進制的操作
數據庫2
# by luffycity.com
# 數據類型
# 數字
# in
# float
# 字符串
# char(4) 定長:存取快 浪費空間 提倡
# varchar(4) 變長:存取慢 節省空間
# 時間
# 內置函數 :now year month day
# datetime
# timestamp
# year date time
# 枚舉和集合
# enum 枚舉單選
# create table t(gender enum('male','female'))
# set 集合多選去重
# create table t(hobby set('抽煙','喝酒'))
# 約束條件
# 非空 not null
# 默認值 default
# 唯一 unique
# 聯合唯一 unique(字段1,字段2) # 姓和名 # ip和端口
# 唯一+int 自增 auto_increment
# 主鍵 primary key (非空+唯一)
# 聯合主鍵 primary key(字段1,字段2)
# 外鍵 foreign key
# 表結構操作
# 創建表結構 *****
# 刪除表結構
# drop table 表名;
# 修改表結構
# alter table 表名 add 字段 數據類型 約束信息 first
# alter table 表名 add 字段 數據類型 約束信息 after 某字段
# alter table 表名 modify 修改數據的數據類型和約束條件
# alter table 表名 modify 已經存在的字段名 新的類型 新的約束 first
# alter table 表名 change 已經存在的字段名 新字段名 新的類型 新的約束 first
# alter table 表名 drop 字段/索引
# 查看表結構 *****
# desc 表名;
# show create table 表名;
數據庫3
# by luffycity.com
# 記錄操作 dml
# 增
# insert into 表 (字段) values (值1,值2,),(值1,值2,),(值1,值2,);
# 刪
# delete from table where 條件
# delete from table;刪除整個表中的數據 ,自增字段的offset還在
# 改
# update 表 set 字段=值,字段2=值2 where 條件
# 查
# 單表
# select id from 表
# where 條件
# group by 字段 是可以使用別名的
# having 過濾條件 只能查select字段中或者group by 或者使用了過濾條件
# order by 排序 asc desc
# limit m,n 從m+1開始,取n條
# having
# select name from 表 having age>20 # 報錯
# select name from 表 group by age having avg(age)>20 # 正確
# select name from 表 having avg(age)>20 # 正確
# select name,age from 表 having age>20 # 正確
# 多表
# 連表查詢
# 子查詢
client
# by luffycity.com
# import socket
#
# sk = socket.socket()
# sk.connect(('127.0.0.1',9000))
# while True:
# sk.send(b'hello')
# print(sk.recv(1024))
# sk.close()
#客戶端
from socket import *
c=socket(AF_INET,SOCK_STREAM)
c.connect(('127.0.0.1',8088))
while True:
msg=input('>>: ')
if not msg:continue
c.send(msg.encode('utf-8'))
data=c.recv(1024)
print(data.decode('utf-8'))
並發編程網絡編程和數據庫的基礎操作