網絡真心很抽象,真心很麻煩,Linux都比網絡好玩。python
1.通訊網絡
首先學了一個paramiko, 主要是其中的ssh和sftp. ssh是用來和遠程的主機創建鏈接和通訊,sftp能夠接收或者發送文件到遠程主機。併發
ssh的代碼寫法以下:app
import paramiko #SSH client ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(hostname="192.168.43.123",port=22,username='liqing',password='1234') stdin,stdout,stderr = ssh.exec_command('df') result = stdout.read() print(result) ssh.close()
須要注意的是,ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())這句話最好都加上,保證將遠程主機加到:known hosts這個文件中。ssh
sftp的代碼寫法以下:async
import paramiko transport = paramiko.Transport(('192.168.80.130',22)) transport.connect(username='qq',password='1234') sftp = paramiko.SFTPClient.from_transport(transport) #從本地上傳文件到遠程端口 local_path = 'Z:\李晴\基礎\day 9 paramito\location.py' sftp.put(local_path,'/home/qq/Desktop/test.py') #從遠程端口下載文件 sftp.get('remove_path','local_path') transport.close()
剛開始的時候,對這個hostname很不理解,由於我沒有裝Linux啊。實際上是我根本不會Linux。爲了實現代碼和做業,只能裝個虛擬機,而後裝一個Linux系統。ui
2.線程(threading)spa
基本的概念:線程是一對代碼的集合;進程是一堆資源的集合。進程是要經過線程才能執行的,因此進程的啓動速度比線程要慢。可是運行以後,進程和線程的速度就沒有區別了。線程能夠建立子線程,父、子線程是相互獨立的,因此父線程結束了,子線程仍是會繼續執行(除非把子線程設置爲守護線程(t.setDaemon(True)))。 可是父進程和子進程就是有關係的,父進程結束了,子進程也跟着結束了。線程
2.1 鎖(線程鎖Mutex,GIL鎖,遞歸鎖)blog
Python有GIL鎖,因此解釋器某一個時段只能讓一條python代碼執行。可是,若是有多個線程同時修改一份數據,那麼可能出現執行屢次,數據錯誤的狀況。緣由是多個線程併發執行,因此拿到修改的數據可能就不是最新的。爲了解決這個問題,就有threading.Lock。也能夠經過設置信號量來設置線程數量(semaphore (信號量))。
2.2 event, queue
若是遇到多個線程,那麼怎麼在線程之間執行切換呢?
方法1:手動切換。用event, 在線程1中的某處設置event.set(),而後線程2去檢查,若是event是set格式,那麼執行A動做。而後線程1到了必定的時間清除event.clear(), 那線程2也就緊跟着執行了B動做。適用於兩個線程,每一個線程都有兩種狀況的模式。
方法2:是一個有序的容器,能夠實現程序的解耦。(使得程序之間相互的依靠性降低,更加獨立)queue.
q = queue.Queue(maxsize=3) #常規的模式是先入先出
q2 = queue.LifoQueue(maxsize=3) #後入先出
q3 = queue.PriorityQueue(maxsize=4) #能夠在放的時候設置一下優先級,那麼取出的時候就會根據優先級來:q3.put((10,'alex'))
3.進程(multiprocessing)
兩個線程是共享內存空間的,因此他們的數據是能夠進行相互交換的;可是兩個進程是有獨立的內存空間的,因此不能共享數據。那要是須要實現兩個進程之間的數據交換,應該如何處理呢?須要建立「紐帶」
3.1 pipe,Queue, Manager()
pipe 須要定義parent_pipe, child_pipe = pipe() 這兩個管道; 在建立子進程的時候,就將管子傳給子進程: p= Process(target = f, args= (child_pipe,) ); parent_pipe 發送數據,child_pipe接受數據,反之亦然。
Queue 須要父進程定義一個q=Queue(); 而後建立子進程的時候,將這個q傳給子進程 p=Process(target = f, args=(q,))。以後子進程能夠向父進程的q放入數據,父進程經過q拿到數據。
Manager能夠生成一個在進程中共享的字典或者列表。d= Manager.dict(), l = Manager.list()
for i in range(10)
p = Process(target=f, args=(d,l))
p.start()
def f(d,l)
d[os.getpid()] = os.getpid()
l.append(os.getpid())
這樣當10個進程執行完畢以後,d和l中就會有10個進程的ID號。至關於每一個進程讀取了相同的文件,而後對文件進行了修改。
3.2 進程池(鎖)
那麼多個進程在執行的時候,會不會也兩個進程同時執行呢?答案是:「會」。可是兩個進程同時執行,最終結果是不會錯誤的,可是可能會引發屏幕輸出混亂。因此進程中經過進程池來控制進程的數量:
from multiprocessing import Pool, Process,freeze_support import time import os def Foo(i): time.sleep(2) print("in process",os.getpid()) return i + 100 def Bar(arg): print("--> exec done:",arg) if __name__ == '__main__': #若是是主動執行這個腳本,那麼就執行;若是是被動執行這個腳本,那麼下面的代碼就不執行。 pool = Pool(5) #容許進程池中最大放入5個進程 for i in range(10): # pool.apply(func= Foo,args=(i,)) #有兩種實用方法, apply是串行,apply_async是並行 pool.apply_async(func=Foo, args=(i,),callback=Bar) #callback回調,等進程執行結束後,自動執行。回調是主進程執行的。 print('end') pool.close() pool.join() #等進程池執行中的進程執行完畢以後再關閉,若是不寫,那麼程序直接關閉。
因此根據線程和進程的鎖狀況,總結了一下:
線程 進程
生成方式 lock = threading.Rlock() lock = Lock()
啓動方式 lock.acquire() lock.acquire()
釋放方式 lock.release() lock.release()
做用 防止線程之間使用數據混亂 防止進程搶着在屏幕上打印數據,出現打印數據的混亂