1. 程式人生 > >Cpython直譯器下實現併發程式設計

Cpython直譯器下實現併發程式設計

一 背景知識

顧名思義,程序即正在執行的一個過程。程序是對正在執行程式的一個抽象。

程序的概念起源於作業系統,是作業系統最核心的概念,也是作業系統提供的最古老也是最重要的抽象概念之一。作業系統的其他所有內容都是圍繞程序的概念展開的。

所以想要真正瞭解程序,必須事先了解作業系統,點選進入    

PS:即使可以利用的cpu只有一個(早期的計算機確實如此),也能保證支援(偽)併發的能力。將一個單獨的cpu變成多個虛擬的cpu(多道技術:時間多路複用和空間多路複用+硬體上支援隔離),沒有程序的抽象,現代計算機將不復存在。

必備的理論基礎:

#一 作業系統的作用:
    1:隱藏醜陋複雜的硬體介面,提供良好的抽象介面
    
2:管理、排程程序,並且將多個程序對硬體的競爭變得有序 #二 多道技術: 1.產生背景:針對單核,實現併發 ps: 現在的主機一般是多核,那麼每個核都會利用多道技術 有4個cpu,運行於cpu1的某個程式遇到io阻塞,會等到io結束再重新排程,會被排程到4個 cpu中的任意一個,具體由作業系統排程演算法決定。 2.空間上的複用:如記憶體中同時有多道程式 3.時間上的複用:複用一個cpu的時間片 強調:遇到io切,佔用cpu時間過長也切,核心在於切之前將程序的狀態儲存下來,這樣 才能保證下次切換回來時,能基於上次切走的位置繼續執行

本文將將著重介紹程序以及它的親戚->執行緒

二 python併發程式設計之多程序

三 python併發程式設計之多執行緒

四 python併發程式設計之協程

五 python併發程式設計之IO模型

六 補充:paramiko模組

1. 介紹:

paramiko是一個用於做遠端控制的模組,使用該模組可以對遠端伺服器進行命令或檔案操作,值得一說的是,fabric和ansible內部的遠端管理就是使用的paramiko來現實。

2. 下載安裝

pip3 install paramiko #在python3中
pycrypto,由於 paramiko 模組內部依賴pycrypto,所以先下載安裝pycrypto #
在python2中 pip3 install pycrypto pip3 install paramiko 注:如果在安裝pycrypto2.0.1時發生如下錯誤 command 'gcc' failed with exit status 1... 可能是缺少python-dev安裝包導致 如果gcc沒有安裝,請事先安裝gcc
在python2中

3. 使用

SSHClient

用於連線遠端伺服器並執行基本命令

基於使用者名稱密碼連線:

import paramiko

# 建立SSH物件
ssh = paramiko.SSHClient()
# 允許連線不在know_hosts檔案中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連線伺服器
ssh.connect(hostname='120.92.84.249', port=22, username='root', password='xxx')

# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
print(result.decode('utf-8'))
# 關閉連線
ssh.close()
import paramiko

transport = paramiko.Transport(('120.92.84.249', 22))
transport.connect(username='root', password='xxx')

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
res=stdout.read()
print(res.decode('utf-8'))

transport.close()
SSHClient 封裝 Transport

基於公鑰金鑰連線:

客戶端檔名:id_rsa

服務端必須有檔名:authorized_keys(在用ssh-keygen時,必須製作一個authorized_keys,可以用ssh-copy-id來製作)

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')

# 建立SSH物件
ssh = paramiko.SSHClient()
# 允許連線不在know_hosts檔案中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連線伺服器
ssh.connect(hostname='120.92.84.249', port=22, username='root', pkey=private_key)

# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
print(result.decode('utf-8'))
# 關閉連線
ssh.close()
View Code
import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')

transport = paramiko.Transport(('120.92.84.249', 22))
transport.connect(username='root', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
result=stdout.read()
print(result.decode('utf-8'))

transport.close()
SSHClient 封裝 Transport 
import paramiko
from io import StringIO

key_str = """-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAsJmFLrSeCumJvga0Gl5O5wVOVwMIy2MpqIyQPi5J87dg89a4
Da9fczJog7qoSbRwHFOQoCHNphSlp5KPhGsF6RJewkIw9H1UKV4dCOyl/4HOAkAD
rKrsEDmrJ9JlzF2GTTZSnTgVQWcvBS2RKB4eM2R9aJ11xV6X2Hk4YDLTExIWeabb
h2TUKw0iyjI8pRuYLKkF2X16u9TBwfOTroGYgiNFHQvhsQppbEbI49NF2XkCkFMi
8/7tLjf95InE/VUUq56JqfzyHwdpHou+waXbwtvGgXN3sz+KkuEv6R2qDz06upZV
FCZRRpDhzoR8Uh/UEzTGZb8z7FB6EJXUiXJikQIBIwKCAQBBmBuGYFf1bK+BGG7H
9ySe81ecqVsJtx4aCFLVRGScWg4RbQKIvXs5an6XU/VdNGQnx0RYvBkvDvuzRRC8
J8Bd4kB0CfTtGJuaVigKoQp02HEWx1HSa17+tlWD0c4KFBvwywi+DYQ83S64x8gz
eOalX9bPFenqORPUD8R7gJeKvPVc6ZTPeorpuH7u9xayP0Eop8qKxZza9Xh3foVj
Qo4IxoYnDN57CIRX5PFSlDDggpmr8FtRF4nAxmFq8LhSp05ivzX/Ku1SNHdaMWZO
7va8tISXdLI5m0EGzoVoBvohIbwlxI6kfmamrh6Eas2Jnsc4CLzMsR4jBWt0LHLv
/SLnAoGBANaEUf/Jptab9G/xD9W2tw/636i3gLpTPY9KPtCcAxqStNeT6RAWZ5HF
lKJg+NKpu3pI45ldAwvts0i+aCZk2xakEWIZWqCmXm31JSPDQTaMGe7H0vOmUaxx
ncdpBVdvhMbfFUgei15iKfuafgrKaS9oIkntXEgrC+3wBOI0Gbx3AoGBANLAGxAF
TK7ydr+Q1+6/ujs6e8WsXt8HZMa/1khCVSbrf1MgACvZPSSSrDpVwaDTSjlRI4AL
bb0l0RFU+/0caMiHilscuJdz9Fdd9Ux4pjROZa3TF5CFhvP7PsZAoxOo+yqJg4zr
996GG/aAv4M8lQJ2rDFk/Dgn5y/AaAun1oM3AoGAGIQmoOPYjY4qkHNSRE9lYOl4
pZFQilKn8x5tlC8WTC4GCgJGhX7nQ9wQ/J1eQ/YkDfmznH+ok6YjHkGlgLsRuXHW
GdcDCwuzBUCWh76LHC1EytUCKnloa3qy8jfjWnMlHgrd3FtDILrC+C7p1Vj2FAvm
qVz0moiTpioPL8twp9MCgYEAin49q3EyZFYwxwdpU7/SJuvq750oZq0WVriUINsi
A6IR14oOvbqkhb94fhsY12ZGt/N9uosq22H+anms6CicoQicv4fnBHDFI3hCHE9I
pgeh50GTJHUA6Xk34V2s/kp5KpThazv6qCw+QubkQExh660SEdSlvoCfPKMCi1EJ
TukCgYAZKY1NZ2bjJyyO/dfNvMQ+etUL/9esi+40GUGyJ7SZcazrN9z+DO0yL39g
7FT9NMIc2dsmNJQMaGBCDl0AjO1O3b/wqlrNvNBGkanxn2Htn5ajfo+LBU7yHAcV
7w4X5HLarXiE1mj0LXFKJhdvFqU53KUQJXBqR6lsMqzsdPwLMJg==
-----END RSA PRIVATE KEY-----"""

private_key = paramiko.RSAKey(file_obj=StringIO(key_str))
transport = paramiko.Transport(('120.92.84.249', 22))
transport.connect(username='root', pkey=private_key)

ssh = paramiko.SSHClient()
ssh._transport = transport

stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read()
print(result.decode('utf-8'))
transport.close()

print(result)
基於私鑰字串進行連線

SFTPClient

用於連線遠端伺服器並執行上傳下載

基於使用者名稱密碼上傳下載

import paramiko
 
transport = paramiko.Transport(('120.92.84.249',22))
transport.connect(username='root',password='xxx')
 
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至伺服器 /tmp/test.py
sftp.put('/tmp/id_rsa', '/etc/test.rsa')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
 
transport.close()
View Code

基於公鑰金鑰上傳下載

import paramiko

private_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')

transport = paramiko.Transport(('120.92.84.249', 22))
transport.connect(username='root', pkey=private_key )

sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至伺服器 /tmp/test.py
sftp.put('/tmp/id_rsa', '/tmp/a.txt')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')

transport.close()
View Code
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import paramiko
import uuid

class Haproxy(object):

    def __init__(self):
        self.host = '172.16.103.191'
        self.port = 22
        self.username = 'root'
        self.pwd = '123'
        self.__k = None

    def create_file(self):
        file_name = str(uuid.uuid4())
        with open(file_name,'w') as f:
            f.write('sb')
        return file_name

    def run(self):
        self.connect()
        self.upload()
        self.rename()
        self.close()

    def connect(self):
        transport = paramiko.Transport((self.host,self.port))
        transport.connect(username=self.username,password=self.pwd)
        self.__transport = transport

    def close(self):

        self.__transport.close()

    def upload(self):
        # 連線,上傳
        file_name = self.create_file()

        sftp = paramiko.SFTPClient.from_transport(self.__transport)
        # 將location.py 上傳至伺服器 /tmp/test.py
        sftp.put(file_name, '/home/root/tttttttttttt.py')

    def rename(self):

        ssh = paramiko.SSHClient()
        ssh._transport = self.__transport
        # 執行命令
        stdin, stdout, stderr = ssh.exec_command('mv /home/root/tttttttttttt.py /home/root/ooooooooo.py')
        # 獲取命令結果
        result = stdout.read()


ha = Haproxy()
ha.run()
Demo

七 作業

題目:簡單主機批量管理工具

需求:

  1. 主機分組
  2. 主機資訊配置檔案用configparser解析
  3. 可批量執行命令、傳送檔案,結果實時返回,執行格式如下 
    1. batch_run  -h h1,h2,h3   -g web_clusters,db_servers    -cmd  "df -h" 
    2. batch_scp   -h h1,h2,h3   -g web_clusters,db_servers  -action put  -local test.py  -remote /tmp/ 
  4. 主機使用者名稱密碼、埠可以不同
  5. 執行遠端命令使用paramiko模組
  6. 批量命令需使用multiprocessing併發

歌曲推薦

1.萬里

4. 歌謠祭1

相關推薦

Cpython直譯器實現併發程式設計

一 背景知識 顧名思義,程序即正在執行的一個過程。程序是對正在執行程式的一個抽象。 程序的概念起源於作業系統,是作業系統最核心的概念,也是作業系統提供的最古老也是最重要的抽象概念之一。作業系統的其他所有內容都是圍繞程序的概念展開的。 所以想要真正瞭解程序,必須事先了解作業系統,點選進入     PS:

python 使用多程序實現併發程式設計/使用queue進行程序間資料交換

import time import os import multiprocessing from multiprocessing import Queue, pool """ 一.Python 使用多程序實現併發程式設計: 因為cpython直譯器中有GIL存在的原因(每個程序都會維護一

快速瞭解Python併發程式設計的工程實現()

關於我 一個有思想的程式猿,終身學習實踐者,目前在一個創業團隊任team lead,技術棧涉及Android、Python、Java和Go,這個也是我們團隊的主要技術棧。 Github:https://github.com/hylinux1024 微信公眾號:終身開發者(angrycode) 0x00 使

Cpython解釋器實現並發編程

all 結束 host 服務器 param ddp 算法 正在 多核 閱讀目錄 一 背景知識 二 python並發編程之多進程 三 python並發編程之多線程 四 python並發編程之協程 五 python並發編程之IO模型 六 補充:paramiko模塊 七

socket程式設計select實現併發處理

//伺服器客戶端均已修改 //伺服器 #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <

併發程式設計的藝術——第二章Java併發機制的底層實現原理

第一節 volatile的應用 定義:Java程式語言允許執行緒訪問共享變數,為了確保共享變數能被準確和一致地更新,執行緒應該確保通過排他鎖單獨獲得這個變數。 為了提高處理速度,處理器不直接和記憶體進行通訊,而是先將系統記憶體的資料讀到內部快取後再進行操作 在多處理器下, 為了保證各個處

Java併發程式設計(6):Runnable和Thread實現多執行緒的區別(含程式碼)

Java中實現多執行緒有兩種方法:繼承Thread類、實現Runnable介面,在程式開發中只要是多執行緒,肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下優勢: 1、可以避免由於Java的單繼承特性而帶來的侷限; 2、增強程式的健壯性,程式碼能夠被多個執行

併發程式設計的三種實現方式

java天生就是多執行緒的程式語言,建立新的執行緒有三種實現方式,分別是: 繼承Thread,實現Runable,實現Callable<T> 程式碼如下: //Thread class ThreadTest extends Thread { @Override pu

Java併發程式設計(10):使用wait/notify/notifyAll實現執行緒間通訊的幾點重要說明

在Java中,可以通過配合呼叫Object物件的wait()方法和notify()方法或notifyAll()方法來實現執行緒間的通訊。線上程中呼叫wait()方法,將阻塞等待其他執行緒的通知(其他執行緒呼叫notify()方法或notifyAll()方法),線上程中呼叫notify()方法或notifyAl

Linux網路socket程式設計——實現伺服器(select)與多個客戶端通訊

Linux下網路socket程式設計——實現伺服器(select)與多個客戶端通訊 置頂 2017年06月23日 14:44:37 閱讀數:3225 標籤: socket程式設計伺服器與多個客戶端通epoll多路複用C語言網路程式設計 更多

併發程式設計系列:ConcurrentHashMap的實現原理(JDK1.7和JDK1.8)

轉載自:https://www.toutiao.com/i6623301848268800519/ HashMap、CurrentHashMap 的實現原理基本都是BAT面試必考內容,阿里P8架構師談:深入探討HashMap的底層結構、原理、擴容機制深入談過hashmap的實現原理

Java併發(十八):阻塞佇列BlockingQueue BlockingQueue(阻塞佇列)詳解 二叉堆(一)之 圖文解析 和 C語言的實現 多執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue(阻塞佇列)詳解

阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者

併發程式設計(三)—— ReentrantLock實現原理及原始碼分析

  ReentrantLock是Java併發包中提供的一個可重入的互斥鎖。ReentrantLock和synchronized在基本用法,行為語義上都是類似的,同樣都具有可重入性。只不過相比原生的Synchronized,ReentrantLock增加了一些高階的擴充套件功能,比如它可以實現公平鎖,同時也可以

Java併發(二十一):執行緒池實現原理 Java併發(十八):阻塞佇列BlockingQueue Java併發(十八):阻塞佇列BlockingQueue Java併發程式設計:執行緒池的使用

一、總覽 執行緒池類ThreadPoolExecutor的相關類需要先了解:  (圖片來自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8%A7%88) Executor:位於最頂層,只有一個 execute(Runnab

Java併發程式設計(二)多執行緒四種實現方式

Java實現多執行緒的方式 Java實現多執行緒的方式有4種: 繼承Thread方法、實現Runnable介面、實現Callable介面並通過FutureTask建立執行緒、使用ExecutorService。 其中,前兩種執行緒執行結果沒有返回值,後兩種是有返回值的。 1、繼承Th

Java 併發程式設計深入學習——執行緒池及其實現原理

Java執行緒池介紹   執行緒池,從字面含義來看,是指管理一組同構工作執行緒的資源池。執行緒池是與工作佇列(work Queue)密切相關的,其中工作佇列中儲存了所有等待執行的任務。工作者執行緒(Work Thread)的任務很簡單:從工作佇列中獲取一個任務,執行任務,然

Java併發程式設計(二)——Java併發底層實現原理

Java程式碼會被編譯後變成Java位元組碼,位元組碼會被類載入器載入到JVM中,JVM執行位元組碼,最終轉化成彙編指令在CPU上執行,Java中所使用的併發機制依賴於JVM的實現和CPU的指令。 volatile 在多執行緒併發程式設計中,synchronized和volatile

Java程式設計師必知的併發程式設計藝術——併發機制的底層原理實現

Java程式語言允許執行緒訪問共享變數,為了確保共享變數能被準確和一致的更新,執行緒應該確保通過排他鎖單獨獲得這個變數。 volatile藉助Java記憶體模型保證所有執行緒能夠看到最新的值。(記憶體可見性) 實現原理: 將帶有volatile變數操作的Java程式碼轉

Java併發程式設計(2) AbstractQueuedSynchronizer的設計與實現

一 前言   上一篇分析AQS的內部結構,其中有介紹AQS是什麼,以及它的內部結構的組成,那麼今天就來分析下前面說的內部結構在AQS中的具體作用(主要在具體實現中體現)。 二 AQS的介面和簡單示例   上篇有說到AQS是抽象類,而它的設計是基於模板方法模式的,也就是說:使用者需要繼承同步器並重寫指定的

併發程式設計----介面聚合 (實現方法)

 併發程式設計 1.在Service中實現多執行緒的返回結果聚合,例如下圖 分三個執行緒,執行緒1、執行緒2、執行緒3來現實使用者資訊系統、使用者餘額系統、使用者積分系統 最後進行返回結果聚合  2。在使用多執行緒的情況下,繼續使用執行緒池來實現減少執行時間。