可貴一逼的web基礎

網絡真心很抽象,真心很麻煩,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()

做用          防止線程之間使用數據混亂                       防止進程搶着在屏幕上打印數據,出現打印數據的混亂

相關文章
相關標籤/搜索