什么是进程?
进程是指系统中正在运行的一个应用程序。进程就好比工厂的车间,它代表cpu所能处理的单个任务。任一时刻,cpu总是运行一个进程,其它进程处于非运行状态。
一个操作系统中它肯定有多个进程,但是多个进程它是互不干扰的。同一时刻只能有一个进程在运行,我们看到的就是一个浏览器Chrome,它的一个进程的消息的一个模型,就是说它每个标签页其实是单独开的一个进程,它就达到了一种互不干扰的,如果你正在看这个标签页的话,它不会影响其它标签页的情况,这个就是一个利用多进程的例子。
为什么使用多进程?
Python中的多线程其实硬不是正真的多线程,如果想要充分地使用多核cpu的资源,在Python中大部分情况需要使用多进程。
Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其它所有事情。借助这个包,可以轻松完成从单进程并发执行的转换。
如何使用多进程实现Paramiko操作?
下面很简单地实现一个多进程版本的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。多进程它的一个特点,就是说它有它的并发性,就是说每一个进程互不影响它们是同是进行的。只要你的机子是多核,它就会充分利用多核的优势来进行查询,然后我们就看到了多进程操作,远程机器的这么一个优点。