程序、執行緒、鎖相關筆記
day1:
淺拷貝:a=b 兩個列表id相同,用的是同一個堆和棧
深拷貝:a=copy.deepcopy(a) 兩個列表id不同,用的是不同的堆和棧
檢視工作管理員 : Shift+Ctrl+Esc
阻塞狀態:等待狀態,程式碼都沒有執行如input等待輸入時
就緒狀態:阻塞結束到執行之前
執行狀態:
程序(1.程序的概念:一個程式的一次執行
2.匯入process模組: from multiprocessing import Process 匯入的是multiprocessing中的process模組 process就是程序模組 建立程序 : p=Process(target=程序體,args=(引數元組) 3.程序子類繼承: from multiprocessing import Process import os class MyProcess(Process): def __init__(self,num): super().__init__() self.num = num def run(self): self.num print("當親程序為子程序 ,子程序ID為%d"%os.getpid()) if __name__ == '__main__': print(os.getpid()) for i in range(10): m = MyProcess(5) m.start() 繼承multiprocessing包的Process模組,當啟動start()方法是,會在類中觸發run()方法建立子程序並呼叫 4.程序池: 程序池:有伺服器預先建立的一組子程序(https://blog.csdn.net/hello_bravo_/article/details/52528283) p=multiprocessing.Pool(程序池容量) p.apply_async(子程序 程序體,引數元組) 非同步執行程序(程序可同時執行) p.apply(.....同上) 同步執行程序(執行完一個才能執行下一個) 程序池中的子程序:程序池在伺服器啟動之初就建立好了,所以每個子程序都相對"乾淨",即它們沒有開啟不必要的檔案描述符(從父程序繼承而來) 也不會錯誤地使用大塊的堆記憶體(從父程序複製得到) 程序池Pool中的apply方法與apply_async的區別(https://www.jianshu.com/p/0a55507f9d9e?open_source=weibo_search) 1.pool=Pool(3) #建立程序池 括號中填程序池的程序容量 不填預設為4個 2.apply(func,args):同步執行 apply方法是阻塞的,意思就是等待當前子程序執行完畢後,在執行下一個程序。 因為apply是阻塞的,所以進入子程序執行後,等待當前子程序執行完畢,在繼續執行下一個程序 首先主程序開始執行,碰到子程序,作業系統切換到子程序,等待子程序執行結束後,在切換到另外一個子程序,直到所有子程序執行完畢。 然後在切換到主程序,執行剩餘的部分。 3.apply_async:非同步執行 apply_async是非同步非阻塞的,意思就是:不用等待當前程序執行完畢,隨時根據系統排程來進行程序切換。 首先主程序開始執行,碰到子程序後,子程序執行,主程序說:讓我先執行個夠,等到作業系統進行程序切換的時候,在交給子程序執行。以為我們的 程式太短,然而還沒等到作業系統進行程序切換,主程序就執行完畢了。 想要子程序執行,就告訴主程序:你等著所有子程序執行完畢後,在執行剩餘部分。join() 4.join() (https://blog.csdn.net/qq_41020281/article/details/79561043) join所完成的工作就是執行緒同步,即主執行緒任務結束之後,進入阻塞狀態,一直等待其他的子執行緒執行結束之後,主執行緒再終止 5.程序間的通訊 必須先例項化Queue類 使用例項化的物件實現程序間的通訊 p=Queue(通訊容量) 如果要放進程序體 q.put('hello') 寫入 print(q.get()) 取出 q.size() 檢測寫入幾個 q.full() 檢測寫滿沒有 滿True q.empty() 空True 非空False
day2:
執行緒(1.執行緒的概念
2.執行緒和程序的區別
3.執行緒的建立
4.執行緒子類的繼承
5.執行緒間的全域性變數是共享的
6.執行緒互斥鎖【執行緒如果頻繁修改全域性變數,會對資料造成一定的誤差】)
建立執行緒(兩個方法:建立或類中繼承建立):import threading(匯入thread模組的包) t=threading.Thread(target=zxc,args=(,)) 互斥鎖:(https://blog.csdn.net/yanhuatangtang/article/details/75316644) from threading import Lock m=Lock() n=m.acquire(False) #上鎖 引數為False時,執行緒沒取到共享變數也會繼續執行,因此要加上if n 不寫引數預設(True),上鎖時取不到共享變數的執行緒會進入阻塞狀態,一直等待共享變數解鎖取到為止,這種寫法 不需要判斷if n if n: num+=1 m.release()
協程:
協程的概念
複習迭代器
複習生成器
協程的編排(使用迭代器和生成器編輯的協程)
http://python.jobbole.com/86481/
生成器的編輯:(生成器中yield返回的值只能被迭代出來)
import time
def A():
while True:
print("=A=")
yield #記住這次執行到這,掛起函式,返回到迭代處,下次執行時從這裡開始繼續執行
time.sleep(1)
def B©:
while True:
print("=B=")
next(c())
time.sleep(1)
B(A())
列表推導式:
lists=[i for i in range(10)]
迭代器:
一般迭代生成器
next()
B(a)
或:
a=iter(迭代物件)
a.next()
greenlet:
from greenlet import greenlet
def A():
…
g2.switch()
…
def B():
…
g1.switch()
g1=greenlet(A)
g2=greenlet(B)
g1.switch()
單例
class Person(object):
__instanse = None
def new(cls,*asd,**sdf):
if cls.__instanse == None:
cls.__instanse = super().new(cls)
return cls.__instanse
def init(self):
print(“這是一個很寂寞的天”)
def start(self):
print(“下著有些傷心的雨”)
p=Person()
m=Person()
print(id§)
print(id(m))
程序執行緒總結(https://blog.csdn.net/a2011480169/article/details/74370184)
day4
套接字:
是支援網路通訊的基本操作單元,可以看做是不同主機之間的程序進行雙向通訊的端點(可看作通訊兩方的一種約定)
通過套接字中的相關函式完成通訊過程(Socket=Ip address+ TCP/UDP + port)port:埠號
UDP(資料報套接字): SOCK_DGRAM
TCP(流式套接字): SOCK_STREAM
互動:(B:瀏覽器 C:客戶端 S:伺服器)
C/S: 客戶端、伺服器互動
B/S: 瀏覽器、伺服器互動
IP:
檢視IP:開啟cmd,打ipconfig
內網:不能上網
外網:能上網
網路埠號:
協議:
udp:使用者資料報協議:無連線的簡單的面向資料報的傳輸層協議(通訊時只負責傳送,是否接收並不負責,會發生丟包)
socket(from socket import *)socket.socket:
udp型別:使用者資料報協議:無連線的簡單的面向資料報的傳輸層協議(通訊時只負責傳送,是否接收並不負責)
通訊只有兩個客戶端:【傳送:udp_socket.sendto(send_data.encode("gb2312"),send_address
接收:get_data=udp_socket.recvfrom(1024))
】
傳送:(核心:udp_socket.sendto(send_data.encode("gb2312"),send_address)):
#建立socket型別: 1.UDP:資料報套接字 2.TCP:流式套接字
#建立UDP使用 SOCK_DGRAM 資料報套接字
#建立TCP使用 SOCK_STREAM 流式套接字
udp_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #建立一個UDP的socket (通訊屬性,socket型別)
#第一個引數:不同電腦間通訊選擇AF_INET(socket包中的一個屬性)
#第二個引數:type 建立的socket的型別(建立UDP使用 SOCK_DGRAM資料報套接字
#建立TCP使用 SOCK_STREAM 流式套接字)
send_address=('傳送方埠號',接收方埠號) #繫結要傳送資料的IP和埠號 也就是接收方的IP地址和埠號 他是一個元組
send_data(變數名)=input(‘請輸入要傳送的資料’)
udp_socket.sendto(send_data.encode("gb2312"),send_address) #傳送資料 使用UPD物件(dup_socket來發送資料
#使用物件中的sendto方法 內建兩個引數
#第一個引數是傳送的資料
#第二個引數是接收方的IP地址和埠號
udp_socket.close() #關閉資源
接收:(核心get_data=udp_socket.recvfrom(1024)):
from socket import *
udp_socket=socket(AF_INET,SOCK_DGRAM)
#如果對方要給我發信息 那麼一定要知道我的IP地址和埠號
#IP地址是已知的 埠號
#當前應繫結我當前程序的埠號
#使用bind方法綁定當前程序的埠號和IP
#內建一個引數 引數是一個元組
address_family=("10.10.86.208",9988)
udp_socket.bind(address_family)
#接收資訊使用recvfrom方法 內建一個引數
#引數是udp物件接收資料的最大值單位是位元組
#然後recvfrom有一個返回值
#返回值是一個元組
#元組中有兩個元素 第一個元素是接收的資料 第二個元素還是一個元組(元組裡面是傳送方的IP和埠號)
get_data=udp_socket.recvfrom(1024)
print(get_data)
#關閉資源
udp_socket.close()
udp_socket.bind()
tcp型別:傳輸控制協議:面向連線的協議(要連線也要斷開。不會丟包,沒傳送或接收到會報錯)
通訊時有伺服器端(被動方)和客戶端(主動方)
伺服器端:
#編輯伺服器 (#1.轉被動;限制客戶端介面量 listen(介面個數)
listen():函式不會阻塞,它主要做的事情為,將該套接字和套接字對應的連線佇列長度告訴 Linux 核心,然後,listen()函式就結束。
#2.建立新socket;接收客戶端地址 accept()
#3.接收客戶端請求 recv(接收位元組容量)
#4.輸出請求 print(請求內容.解碼)
#5.傳送響應 send(響應內容.轉碼)
#6.關閉新socket close()
)
客戶端:
#編輯客戶端 (#1.連線地址 connect((ip,埠號))
#2.傳送請求 send(請求內容.轉碼)
#3.接收響應 recv(接收位元組容量)
#4.輸出響應 print(響應內容.解碼)
)
三次握手四次揮手
握手:
客戶端向伺服器:【0請求連線】
syn(0)---ack(1)
伺服器向客戶端:【同意連線+1,0確定是否連線】
+1,syn(0)---ack(1)
客戶端向伺服器:【確定連線+1】
+1,syn(0)---ack(1)
揮手:fin(0) ack(1)
客戶端向伺服器:【0關閉】
fin(0)---ack(1)
伺服器向客戶端:【確認關閉+1,0客戶端關閉】
+1,fin(0)---ack(1)
伺服器向客戶端:【0請求獲取資源】
fin(0)---ack(1)
客戶端向伺服器:【送還資源+1,伺服器關閉資源】
+1,fin(0)---ack(1)
new()new方法:(https://www.cnblogs.com/kex1n/p/5991249.html)
class object:
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" T.__new__(S, ...) -> a new object with type S, a subtype of T """
pass
1.__new__() 函式:
只能用於從object繼承的新式類
object將__new__()方法定義為靜態方法,並且至少需要傳遞一個引數cls,cls表示需要例項化的類,此引數在例項化時由Python直譯器自動提供。
例項化物件的時候,呼叫__init__()初始化之前,先呼叫了__new__()方法
__new__()必須要有返回值,返回例項化出來的例項
需要注意的是,可以return父類__new__()出來的例項,也可以直接將object的__new__()出來的例項返回。
2.與__init__()init方法:
__init__()有一個引數self,該self引數就是__new__()返回的例項
__init__()在__new__()的基礎上可以完成一些其它初始化的動作,__init__()不需要返回值。
若__new__()沒有正確返回當前類cls的例項,那__init__()將不會被呼叫,即使是父類的例項也不行。
我們可以將類比作製造商,__new__()方法就是前期的原材料購買環節,__init__()方法就是在有原材料的基礎上,加工,初始化商品環節。
day5
python:
r:阻止轉義,原字串輸出
正則表示式:(https://www.cnblogs.com/xiaxiaoxu/p/8436795.html)
import re
方法:
re.match()方法 引數2('',string).group() 從頭開始匹配
re.search()方法 全域性查詢
re.sub()方法 引數3('被替換的字串',‘替換的字串’,s(原字串))替換
re.findall() 引數2(正則,string) 符合條件的收入列表
re.DOTALL :
re.M :re.M表示將字串視為多行,從而^匹配每一行的行首,$匹配每一行的行尾
re.split2(":|;",string) 切割
普通轉義字元(背):
\ : 轉義符(轉義一下)
\d:匹配的是0--9任意一位數字
\D: 匹配的是任意一位非數字 除了數字以外的任意字元都可以
\w:匹配任意一位數字字母下劃線
\W:匹配除了數字字母下劃線任意一位字元
\s:匹配任意一位空白字元\r(換行?),\n(空行?),\t(製表符),\v(垂直製表符),\f(換頁符),空格
\S:匹配任意一位非空白字元
\b: 匹配字單詞的邊界
\B: 匹配除單詞邊界以外的部分
^或\A:放正則表示式第一位匹配字串串首的原子,放原子第一位是“非”的意思,其他位置就是一個原子
$或\Z: 匹配字串串尾的原子放結尾,固定了最後一位
?:匹配其前原子0次或一次()
+ :匹配其前原子1次或多次(匹配不上,不成功,會報錯)
* :匹配其前原子0次,1次或多次(沒有匹配字串,會匹配成功,結果為空,不會報錯)
| :或,匹配兩個或多個選擇。與邏輯或相同
. :匹配除換行符以外的任意字元
.*: 無敵組合,沒碰到換行\n,一直匹配
(): 整體表示一個原子 print(ret.group(2)) 輸出第二個括號返回的值
:
:二進位制
:八進位制
:十進位制
:十六進位制
i:不區分大小寫
原子表[]:原子表裡面內建多個原子,在原子表中 每個原子都是平等的
貪婪匹配{}:在符合規則的情況下儘可能地多匹配
{m}:匹配其前原子m次
{m,}:匹配其前原子至少m次
{,n}:匹配其原子最多n次
{m,n}:匹配其前原子至少m次 匹配其前原子最多n次
\r:預設表示將輸出的內容返回到第一個指標,這樣的話,後面的內容會覆蓋前面的內容
day6
URL:(協議、域名、埠、路徑、錨)
U-協議http
R-域名www.com 可能跟埠
L-路徑:可能跟引數 引數後可能跟錨
web:
編輯web伺服器:(response_header = "Server: DogBrother" + "\r\n"
response_body = "hello 楊夢圓"
response = response_start_line + response_header + "\r\n" + response_body
new_socket.send(response.encode("gbk"))
)
#編輯web伺服器
from socket import *
tpc_server_socket = socket(AF_INET,SOCK_STREAM)
tpc_server_socket.bind(('',8080))
tpc_server_socket.listen(128)
while True:
new_socket,client_address = tpc_server_socket.accept()
request_data = new_socket.recv(2048)
response_start_line = "HTTP/1.1 200 OK" + "\r\n"
response_header = "Server: DogBrother" + "\r\n"
response_body = "hello 楊夢圓"
response = response_start_line + response_header + "\r\n" + response_body
new_socket.send(response.encode("gbk"))
new_socket.close()
tpc_server_socket.close()
/:根目錄
./:當前目錄
../:上級目錄
sum(num)函式傳參:複製
問題: 套接字
類方法靜態方法等
#\r,\n區別?
數字型別:4種
資料型別:6
join()
1.practice 29行(程序池)apply_sync(p_son)為什麼不用加括號,也不能寫target= Thread(zxc())
2.程序池子類繼承?
3.Queue() 括號內表示的是什麼的容量,怎麼用
4.迭代器,生成器,裝飾器描述
5.淺拷貝,深拷貝
6.正則中的r
7.# ?????????
# import re
# line = "IF_MIB::=Counter32: 12345\nIF_MIB::=Counter32: 1234556";
# result = re.findall(r'(?<=\:\s)\d+$', line, re.M)
# print(result)
8.匹配\home關鍵字:
re.findall(r"\\home","skjdfoijower \home \homewer")
結果:['\\home', '\\home'] 多出來的\不能消掉麼
匹配郵箱:
匹配身份證:
9.listen(2):web伺服器中被動監聽2怎麼理解 (os.pid())
複習: 互斥鎖
程序池()