进程是指系统中正在运行的一个应用程序。进程就好比工厂的车间,它代表cpu所能处理的单个任务。任一时刻,cpu总是运行一个进程,其它进程处于非运行状态。
一个操作系统中它肯定有多个进程,但是多个进程它是互不干扰的。同一时刻只能有一个进程在运行,我们看到的就是一个浏览器Chrome,它的一个进程的消息的一个模型,就是说它每个标签页其实是单独开的一个进程,它就达到了一种互不干扰的,如果你正在看这个标签页的话,它不会影响其它标签页的情况,这个就是一个利用多进程的例子。
Python中的多线程其实硬不是正真的多线程,如果想要充分地使用多核cpu的资源,在Python中大部分情况需要使用多进程。
Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其它所有事情。借助这个包,可以轻松完成从单进程并发执行的转换。
下面很简单地实现一个多进程版本的paramiko连接远程服务器。本章是接着Python远程连接模块Paramiko使用这篇文章来完成多进程实现paramiko操作的。
之前我建立一个文件,叫做config.conf
[ssh] host=10.10.0.112 port=22 username=root password=123456 timeout=1.0
被封装过的代码如下:
import paramiko import configparser class ParamikoClient: def __init__(self, file): self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.config = configparser.ConfigParser() self.config.read(file) def connect(self): try: self.client.connect( hostname = self.config.get('ssh','host'), port = self.config.getint('ssh','port'), username = self.config.get('ssh','username'), password = self.config.get('ssh','password'), timeout = self.config.getfloat('ssh','timeout') ) except Exception as e: print(e) try: self.client.close() except: pass def runcmd(self, cmd): stdin, stdout, stderr = self.client.exec_command(cmd) return stdout.read().decode()
单进程直接这么使用即可:
from ParamikoClient import ParamikoClient def process(): client = ParamikoClient('config.conf') client.connect() client.runcmd('date') if __name__ == '__main__': process()
这就是在一个进程内来处理这个paramiko的操作。一个process它其实在这个main函数里面,它就在这个进程里面运行了,然后如果我们要用多个进程的时候,我们可以这样设计config。
[ssh1] host=10.10.0.112 port=22 username=root password=123456 timeout=1.0 [ssh2] host=10.10.0.112 port=22 username=root password=123456 timeout=1.0 [ssh3] host=10.10.0.112 port=22 username=root password=123456 timeout=1.0
我们可以让它有多个section,一个进程运行一个section。
首先改动ParamikoClient.py脚本,如下:
import paramiko import configparser class ParamikoClient: def __init__(self, file, section): self.client = paramiko.SSHClient() self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) self.config = configparser.ConfigParser() self.config.read(file) self.section = section def connect(self): try: self.client.connect( hostname = self.config.get(self.section,'host'), port = self.config.getint(self.section,'port'), username = self.config.get(self.section,'username'), password = self.config.get(self.section,'password'), timeout = self.config.getfloat(self.section,'timeout') ) except Exception as e: print(e) try: self.client.close() except: pass def runcmd(self, cmd): stdin, stdout, stderr = self.client.exec_command(cmd) return stdout.read().decode()
然后写一个多进程调用脚本,如下:
from ParamikoClient import ParamikoClient from multiprocessing import Pool import time def process(section): client = ParamikoClient('config.conf', section) client.connect() a = client.runcmd('date') print(a, end='') task_num = 3 if __name__ == '__main__': # single process time; start = time.time() pool = Pool() process('ssh1') process('ssh2') process('ssh3') print(time.time() - start) # multi process time; start = time.time() task_num = task_num + 1 for i in range(1, task_num): section = 'ssh'+str(i) pool.apply_async(process, args=(section, )) pool.close() pool.join() print(time.time() - start)
执行结果如下:
$ python process.py Tue Oct 24 04:29:10 EDT 2017 Tue Oct 24 04:29:10 EDT 2017 Tue Oct 24 04:29:10 EDT 2017 0.6342382431030273 Tue Oct 24 04:29:11 EDT 2017 Tue Oct 24 04:29:11 EDT 2017 Tue Oct 24 04:29:11 EDT 2017 0.2790086269378662
从结果可以看到时间缩短了2/3。多进程它的一个特点,就是说它有它的并发性,就是说每一个进程互不影响它们是同是进行的。只要你的机子是多核,它就会充分利用多核的优势来进行查询,然后我们就看到了多进程操作,远程机器的这么一个优点。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/119376.html