python學習筆記9
Paramiko模塊:
paramiko模塊導入:cmd-->pip install paramiko
SSHClient密碼連接:
import paramiko # 創建SSH對象 ssh = paramiko.SSHClient() # 允許連接不在know_hosts文件中的主機 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務器 ssh.connect(hostname=‘c1.salt.com‘, port=22, username=‘wupeiqi‘, password=‘123‘)# 執行命令 stdin, stdout, stderr = ssh.exec_command(‘df‘)#返回標準輸入,標準輸出,標準錯誤 # 獲取命令結果 result = stdout.read() # 關閉連接 ssh.close()
ssh密鑰:
RSA--非對稱密鑰驗證
分為公鑰(public key)和私鑰(private key),公鑰和私鑰成對出現,有私鑰的用戶可以無密碼連接有公鑰的用戶。
#ssh 秘鑰連接,生成秘鑰需要在linix系統上 import paramiko private_key = paramiko.RSAKey.from_private_key_file(‘/home/auto/.ssh/id_rsa‘)#指定私鑰的位置 # 創建SSH對象 ssh = paramiko.SSHClient() # 允許連接不在know_hosts文件中的主機 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務器 ssh.connect(hostname=‘c1.salt.com‘, port=22, username=‘wupeiqi‘, pkey=private_key) # 執行命令 stdin, stdout, stderr = ssh.exec_command(‘df‘) # 獲取命令結果result = stdout.read() # 關閉連接 ssh.close()
SFTPClient文件上傳和下載:
import paramiko # 創建SSH對象 ssh = paramiko.SSHClient() # 允許連接不在know_hosts文件中的主機 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 連接服務器 ssh.connect(hostname=‘c1.salt.com‘, port=22, username=‘wupeiqi‘, password=‘123‘) # 執行命令 stdin, stdout, stderr = ssh.exec_command(‘df‘)#返回標準輸入,標準輸出,標準錯誤 # 獲取命令結果 result = stdout.read() # 關閉連接 ssh.close()
線程與進程:
線程:線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。(一堆指令)
進程:程序要以一個整體的形式暴露給操作系統管理,裏面包含對各種資源的調用,內存的管理,網絡接口的調用等。對各種資源管理的集合,就可以稱為進程。一個程序的執行實例稱為一個進程。每一個進程的內存都是獨立的,互相不能直接訪問。進程要操作cpu必須要先創建一個線程。
啟動一個線程比啟動一個進程快,線程與進程的運行速度沒有可比性,進程是線程的集合,不同線程運行速度看具體情況。
進程與線程的區別:
1、線程之間共享進程創造的內存地址。進程之間的內存空間獨立。
2、線程可以直接訪問進程裏的數據片段。進程有屬於自己的數據段,進程之間不能互相訪問。
3、線程可以直接和同進程裏的線程進行數據交互。兩個進程要通信,必須通過一個中間代理來實現。
4、新的線程容易創建。新的進程需要克隆父類進程創建。
5、一個線程可以控制和操作同一個進程裏的其他線程。但是進程只能操作子進程。
6、對主線程的修改(取消、修改優先級)可能會影響其他同進程下的線程。對父進程的修改不會影響子進程。
守護線程deamon:
主線程關閉時,守護線程自動關閉,由守護線程啟動的其他子線程也會關閉。非守護線程全退出後,程序馬上退出。守護線程優先級很低。
線程的調用方式:
#直接調用方式 import threading,time StartTime=time.time() t_obj=[] def run(x,y): time.sleep(2) print(x,y,x+2*y,‘當前線程:%s‘%threading.current_thread()) t1=threading.Thread(target=run,args=(5,2))#創造線程 t2=threading.Thread(target=run,args=(3,4)) t1.start()#啟動線程 t_obj.append(t1) #join(timeout=None),timeout為超時時間,即最大等待時間 #t1.join()#=t1.wait()等待t1線程執行完,才開始執行後面的代碼 t2.start() t_obj.append(t2) #t2.join()#=t2.wait()等待t2線程執行完,才開始執行後面的代碼 print(t1.getName()) #獲取線程名 print(t2.getName()) #t1和t2並發運行,同時進行time.sleep #啟動多個線程 for i in range(3,50): t=threading.Thread(target=run,args=(i,2)) t.setDaemon(True)#把線程t設置為主線程的守護線程,必須在start之前設置 t.start() #t_obj.append(t) #主線程與子線程是並行狀態 print(‘活躍的線程個數:‘,threading.active_count())#打印正在運行的線程個數 for t in t_obj:#等待所有子線程結束 t.join() EndTime=time.time() print(‘總共運行時間‘,EndTime-StartTime) print(‘主線程:‘,threading.current_thread())#打印當前線程 print(‘活躍的線程個數:‘,threading.active_count()) # run(5,2) # run(3,4) # #按順序運行
#繼承時調用,效果與直接調用相同 import threading,time class MyThreading(threading.Thread): def __init__(self,x,y,sleep_time): super(MyThreading, self).__init__() self.x=x self.y=y self.sleep_time=sleep_time def run(self):#函數名必須為run time.sleep(self.sleep_time) print(self.x, self.y, self.x + 2 * self.y) print(‘task done‘) t1=MyThreading(5,2,5) t2=MyThreading(3,4,1) t1.start() t2.start()
GIL(Globe Interpreter Lock):全局解釋器鎖。即使是多核系統,在同一時間,只會有一個線程在運行。(cpython缺陷)
線程鎖(互斥鎖Mutex):保證鎖住部分處於一個串行狀態。
#線程鎖(互斥鎖Mutex),保證鎖住部分處於一個串行狀態 import threading,time numb=0#定義全局變量 def run(): #lock.acquire()#獲取一把鎖 global numb#訪問全局變量 time.sleep(2) numb+=1 #ock.release()#釋放鎖 t_obj=[] #lock=threading.Lock()#聲明lock實例,線程鎖,保證鎖住部分處於一個串行狀態 for i in range(100): t=threading.Thread(target=run,name=‘threading-%s‘%i) t.start() print(t.getName()) t_obj.append(t) for t in t_obj: t.join() print(‘numb:‘,numb)
遞歸鎖RLock:當線程鎖裏還存在線程鎖時,需要使用遞歸鎖,否者陷入死循環。
#遞歸鎖Rlock import threading, time def run1(): print("grab the first part data") lock.acquire() global num num += 1 lock.release() return num def run2(): print("grab the second part data") lock.acquire() global num2 num2 += 1 lock.release() return num2 def run3(): lock.acquire() res = run1() print(‘--------between run1 and run2-----‘) res2 = run2() lock.release() print(res, res2) if __name__ == ‘__main__‘: num, num2 = 10, 10 lock = threading.RLock()#有多層lock時,必須用RLock。 for i in range(10): t = threading.Thread(target=run3) t.start() while threading.active_count() != 1: print(threading.active_count()) else: print(‘----all threads done---‘) print(num, num2)
semaphore信號量:
互斥鎖同時只允許一個線程更改數據,而Semaphore是同時允許一定數量的線程更改數據,由信號量大小決定。
#semaphpore信號量 #互斥鎖 同時只允許一個線程更改數據,而Semaphore是同時允許一定數量的線程更改數據 import threading, time def run(n): semaphore.acquire() time.sleep(1) print("run the thread: %s\n" % n) semaphore.release() if __name__ == ‘__main__‘: semaphore = threading.BoundedSemaphore(5) # 最多允許5個線程同時運行,單次最大同時運行為5個,每完成一個,等候的線程接上。 for i in range(20): t = threading.Thread(target=run, args=(i,)) t.start() while threading.active_count() != 1: pass # print threading.active_count() else: print(‘----all threads done---‘)
Event標誌位使用:
Event事件
event=threading.Event()生成一個Event對象
event.set()設置變量,服務端線程可以設定標誌位
event.clear()清除,服務端線程可以清除標誌位
event.wait()等待,如果標誌位被設定,wait()不會被堵塞;如果標誌位被清空,wait()會繼續堵塞。多個線程可以等待一個event
使用示例(紅綠燈程序):
# Event事件 # event=threading.Event()生成一個Event對象 # event.set()設置變量,服務端線程可以設定標誌位 # event.clear()清除,服務端線程可以清除標誌位 # event.wait()等待,如果標誌位被設定,wait()不會被堵塞;如果標誌位被清空,wait()會繼續堵塞。多個線程可以等待一個event #示例(紅綠燈): import threading,time event=threading.Event() def TrafficLight(): while True: event.set() print(‘\033[42;1m Green traffic light is on...\033[0m‘) time.sleep(20) event.clear() print(‘\033[41;1m Red traffic light is on...\033[0m‘) time.sleep(10) def car(name): while True: if event.is_set(): print(‘[%s] Running....‘%name) else: print(‘%s seeing red traffic light .Waitting...‘%name) event.wait() print(‘%s go go go‘%name) time.sleep(1) t1=threading.Thread(target=TrafficLight) t1.start() t2=threading.Thread(target=car,args=(‘aodi‘,)) t2.start() t3=threading.Thread(target=car,args=(‘baoma‘,)) t3.start() t4=threading.Thread(target=car,args=(‘luhu‘,)) t4.start()
queue隊列:
特性:數據有序,取走後便消失
class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #last in fisrt out(縮寫Lifo)
class queue.PriorityQueue(maxsize=0) #存儲數據時可設置優先級的隊列
Queue.put(item, block=True, timeout=None)數據放入隊列
Queue.get(block=True, timeout=None)從隊列中取出數據
Queue.qsize()return隊列的大小
Queue.full()如果隊列是滿的話,return Ture
Queue.empty()如果隊列為空,return Ture
Queue.join() block直到queue被消費完畢
#queue隊列:數據有序,取走後便消失 # class queue.Queue(maxsize=0) #先入先出 # class queue.LifoQueue(maxsize=0) #last in fisrt out(縮寫Lifo) # class queue.PriorityQueue(maxsize=0) #存儲數據時可設置優先級的隊列 # Queue.put(item, block=True, timeout=None)數據放入隊列 # Queue.get(block=True, timeout=None)從隊列中取出數據 # Queue.qsize()return隊列的大小 # Queue.full()如果隊列是滿的話,return Ture # Queue.join() block直到queue被消費完畢 import queue q=queue.Queue(maxsize=3)#生成一個queue的對象,maxsize默認不限制大小,maxsize為隊列中最大存放數目,maxsize小於等於0,則為無限大 name=‘wulihui‘ q.put(name)#放入數據 q.put(‘list1‘) q.put(‘list2‘) #q.put(‘list3‘)#放入數據超過maxsize,程序卡住,直到隊列中有數據取出 print(q.full())#隊列滿了,返回Ture,沒滿返回False print(q.qsize())#返回隊列裏項目的個數 print(q.get())#取數據,先入先出,無法改變順序,取完後數據從隊列中消失 print(q.get()) #print(q.get()) #print(q.get())沒有數據時會堵塞,一直等數據加入,程序卡住 print(q.get_nowait())#取不到數據,則拋出異常queue.Empty,有數據則會取出 #print(q.get(block=False))效果等於print(q.get_nowait()) print(q.empty())#隊列為空返回Ture,否者返回False print(‘----------------------------PriorityQueue----------------‘) q2=queue.PriorityQueue()#實例化可設優先級隊列 q2.put((5,‘zhaoyun‘))#傳入一個元組,第一個為用來排序的字符,從小到大,第二個為item q2.put((-3,‘diaocan‘)) q2.put((1000,‘nvbu‘)) q2.put((-1800,‘baiqi‘)) print(q2.get()) print(q2.get()) print(q2.get()) print(q2.get())
生產者消費者模型:
生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞隊列來進行通訊,所以生產者生產完數據之後不用等待消費者處理,直接扔給阻塞隊列,消費者不找生產者要數據,而是直接從阻塞隊列裏取,阻塞隊列就相當於一個緩沖區,平衡了生產者和消費者的處理能力。
模型示例:
import queue,threading,time,random q=queue.Queue(maxsize=10) def producer(name): numb = 1 while True: q.put(‘骨頭%s‘%numb) print(‘%s 生產了骨頭%s‘%(name,numb)) numb=numb+1 time.sleep(random.randint(0,2)) def comsumer(name): while True: print(‘%s has eat the %s...‘%(name,q.get())) time.sleep(random.randint(0,4)) p=threading.Thread(target=producer,args=(‘狗糧1廠‘,)) c=threading.Thread(target=comsumer,args=(‘shamoye‘,)) c2=threading.Thread(target=comsumer,args=(‘bixiong‘,)) p.start() c.start() c2.start()
python學習筆記9