2017-05-17 2 views
0

Ich habe ein einfaches Multiprocess-Pool-Skript mit Map, um die Ergebnisse in geordneter Reihenfolge zurückzuliefern, als ob sie nacheinander ausgeführt würde.Python-Multiprocessing-Map gibt ungeordnete Ergebnisse zurück

Hinweis - Bitte ignorieren Sie die "(1-3A-D)". Sie sind nicht Teil der Ausgabe und dienen zur Veranschaulichung. Angenommen, es wird die Sequenz-Multiprocessing ausgeführt.

import base64 
import getpass 
import os 

from ssh.ssh_module import SSH 
from multiprocessing import Pool 

username = '' 
password = '' 
cmd = 'uptime' 

def runcommand (server): 

    print ('Proccess ID: %d' % (os.getpid())) 
    ssh = SSH (server, username, password) 
    if ssh.connect(): 
     print (ssh.command (cmd)) 

    ssh.close() 


if __name__ == '__main__': 

    username = input ('Username: ') 
    # Encode password for SSH 
    password = getpass.getpass ('Password: ') 
    password = base64.b64encode (password.encode('utf-8')) 

    servers = ['192.168.100.1', '192.168.100.2', '192.168.100.3'] 
    with Pool (processes = 2) as pool: 
     pool.map (runcommand, servers) 

Ausgang:

(virtual) [[email protected] python]$ ./multiprocess.py 
Username: spongebob 
Password: 
(1A) Proccess ID: 24528 
(1B) SSH into 192.168.100.1 
(2A) Proccess ID: 24529 
(2B) SSH into 192.168.100.2 
(1C) Successfully logged in! 
    00:15:24 up 4 days, 8:16, 0 users, load average: 0.12, 0.10, 0.20 

(1D) SSH session closed. 

(3A) Proccess ID: 24529 
(3B) SSH into 192.168.100.3 
(2C) Successfully logged in! 
    00:15:26 up 7 days, 6:17, 0 users, load average: 0.10, 0.11, 0.09 

(2D) SSH session closed. 

(3C) Successfully logged in! 
    00:15:47 up 5 days, 6:41, 0 users, load average: 0.14, 0.10, 0.17 

(3D) SSH session closed. 

Wie Sie sehen können, werden die Ergebnisse zurückgegeben zufällig die ich dachte, 'pool.map' mit angeblich bestellt werden. Die Reihenfolge, in der IPs/System zuerst ausgeführt werden, ist nicht wichtig, aber die Ausgabe muss in der richtigen Reihenfolge sein, so dass es sinnvoll ist. Irgendeine Idee, wie man es beheben kann, damit ich die Wunschausgabe unten bekommen kann?

(1A) Proccess ID: 24528 
(1B) SSH into 192.168.100.1 
(1C) Successfully logged in! 
    00:15:24 up 4 days, 8:16, 0 users, load average: 0.12, 0.10, 0.20 

(1D) SSH session closed. 

(2A) Proccess ID: 24529 
(2B) SSH into 192.168.100.2 
(2C) Successfully logged in! 
    00:15:26 up 7 days, 6:17, 0 users, load average: 0.10, 0.11, 0.09 

(2D) SSH session closed. 

(3A) Proccess ID: 24529 
(3B) SSH into 192.168.100.3 
(3C) Successfully logged in! 
    00:15:47 up 5 days, 6:41, 0 users, load average: 0.14, 0.10, 0.17 

(3D) SSH session closed. 

Antwort

0

Pool.map gibt die Ergebnisse in der gleichen Reihenfolge, wie sie geplant waren, aber nicht gewährleisten, dass sie in der gleichen Reihenfolge ausgeführt werden.

Sequenzielle Ausführung würde den Zweck der Verwendung multiprocessing besiegen. Wenn Sie Dinge nacheinander ausführen möchten, verwenden Sie einfach map.

+0

Wenn was du sagst, ist wahr, was ist dann der Zweck imap_unordered()? – dreamzboy

+0

'imap_unordered' stellt nicht sicher, dass die Ergebnisse geordnet sind. Keine der 'map'-basierten Methoden stellt sicher, dass die * Ausführung * der angegebenen Funktion in der richtigen Reihenfolge angezeigt wird. Um es auszuprobieren, gib einfach den 'server' Parameter von deiner' runcommand' Funktion zurück. Sie werden sehen, dass "map" sie in der gleichen Reihenfolge zurückgibt, während "imap_undordered" dies nicht tut. – noxdafox

+0

Was Sie erreichen wollen, ist, auf 'stdout' in einer geordneten Weise zu loggen, die unmöglich zu gewährleisten ist, da die verschiedenen Prozesse unterschiedliche Zeiten benötigen, um ihre Logik auszuführen. Es ist sehr wahrscheinlich, dass process1 nach process2 protokolliert wird, wenn die SSH-Befehle unterschiedliche Ausführungszeiten benötigen (z. B. Netzwerk-Hiccup). Siehe: https://docs.python.org/2/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes – noxdafox

0

Ich habe es geschafft, die gewünschte Ausgabe zu erreichen, indem ich die Nachrichten innerhalb der SSH-Klasse lösche und sie zum Aufrufer verschiebe. Es ist eine Frage der Verwendung von .join(), um die Nachrichtensequenz zu konstruieren. Es ist nicht das Schönste, aber jetzt ist es bestellt.

import base64 
import getpass 
import os 

from cet.ssh_module import SSH 
from multiprocessing import Pool 

username = '' 
password = '' 
cmd = 'uptime' 


def runcommand (server): 

    print ('Proccess ID: %d' % (os.getpid())) 
    ssh = SSH (server, username, password) 
    s1 = 'SSH into %s' % server 
    if ssh.connect(): 
     s2 = 'Successfully logged in!' 
     s3 = ssh.command (cmd) 

     ssh.close() 
     s4 = 'SSH session closed.\n' 

     output = '\n'.join ([s1, s2, s3, s4]) 

     return output 
    else: 
     pass 


if __name__ == '__main__': 

    servers = ['192.168.100.1', '192.168.100.2', '192.168.100.3'] 

    username = input ('Username: ') 
    # Encode password for SSH 
    password = getpass.getpass ('Password: ') 
    password = base64.b64encode (password.encode('utf-8')) 

    with Pool (processes = 4) as pool: 
     results = pool.map (runcommand, servers) 

    for i in results: 
     print (i) 

Ausgabe

(virtual) [[email protected] python]$ ./multiprocess.py 
Username: spongebob 
Password: 
Proccess ID: 40764 
Proccess ID: 40763 
Proccess ID: 40766 
SSH into 192.168.100.1 
Successfully logged in! 
17:25:33 up 8 days, 23:51, 0 users, load average: 3.04, 2.05, 1.43 

SSH session closed. 

SSH into 192.168.100.2 
Successfully logged in! 
17:25:17 up 2 days, 1:26, 0 users, load average: 0.44, 0.42, 0.72 

SSH session closed. 

SSH into 192.168.100.3 
Successfully logged in! 
17:25:15 up 8 days, 23:27, 0 users, load average: 2.37, 2.35, 2.03 

SSH session closed. 
Verwandte Themen