Update 27. April 2018: Formatierung reparieren
Ich habe gerade eine Frage zur gleichzeitigen Verwendung mehrerer RunProgram-Instanzen erhalten.Hier ist ein Beispiel, das drei Kopien von PING mit drei verschiedenen IP-Adressen ausführt und die Ergebnisse in drei verschiedenen Datentabellen aufzeichnet.Das Beispiel zeigt, wie der "Parameter"-Wert verwendet wird, damit jedes RunProgram weiß, welche Datentabelle verwendet werden soll.Der Anhang ist derselbe wie der Inline-Code ...
// first, we'll need containers that can be indexed from 1 to NJOBS
// and hold the references to the data tables and the RunPrograms.
datatab = Associative Array();
runprog = Associative Array();
who = {"jmp.com", "google.com", "bing.com"}; // each runProgram can do something different
NJOBS = N Items( who );
// next, a loop to make tables and launch the RunPrograms
For( iJOB = 1, iJOB <= NJOBS, iJOB++,
// make a table with a text column, then make the column wide so we can see more data
datatab[iJOB] = New Table( who[iJOB], addrows( 1 ), New Column( "text", Character, Set Values( {"pinging..."} ) ) );
datatab[iJOB]:text << setdisplaywidth( 500 );
// launch the RunProgram. It is particularly important to make sure the RunProgram
// object is stored in a variable that won't be overwritten...the associative array holds it.
runprog[iJOB] = RunProgram(
Executable( "PING.EXE" ), // this is the 'job' we are running several copies of, in parallel
Options( {"-n 10", who[iJOB]} ), // run for 10 seconds --- this is a PING option
Parameter( iJOB ), // remember which "instance" this is --- this goes to the ReadFunction
ReadFunction( // define a function that will get called for lots of small snippets of text
Function( {this, myInstance}, // myInstance is the iJOB
{buffer = ""}, // local to this instance. buffer up small snippets
While( this << canread, // this reads multiple snippets that may show up in a single call
buffer = buffer || (this << read); // put the snippets together
Wait( .01 ); // this isn't really needed except to get the snippets in a single record
); // gather as much as possible
buffer = Regex( buffer, "\s+", " ", GLOBALREPLACE ); // clean up the buffer, remove CRs and LFs
If( Trim( buffer ) != "", // see if we have something to say. there are blanks in PING's output
(datatab[myInstance]) << addrow( 1 ); // my table gets a new row
(datatab[myInstance]):text = buffer; // store the cleaned up buffer
);
)
)
);
);
// if you want to, you can wait for the runprograms. They *require* JMP to be idle to make
// the callback to the read function; the following polling loop uses wait(.1) to make sure
// JMP is mostly idle. When the PING program terminates, it closes the STDOUT file handle
// JMP is listening to, causing the isReadEof message to return TRUE.
For( iJOB = 1, iJOB <= NJOBS, iJOB++,
While( !((runprog[iJOB]) << isReadEof), Wait( .1 ) )
);
Write( "All Done!\!n" ); // now you can proceed with the data tables

Es gibt eine Begrenzung, wie viele davon Sie gleichzeitig ausführen können.Wahrscheinlich nicht Hunderte; Sie verwenden Ressourcen auf Ihrem Computer, die nicht unbegrenzt sind.
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />In JMP 11 konnten Sie das Skript ändern, um eindeutige ReadFunctions für jede RunProgram-Instanz zu verwenden.Dieses Beispiel bettet die Variable "myInstance" in die lokale Variablenliste ein, mit einer Zuweisung, die durch den Mechanismus Eval( EvalExpr( ... expr() ... aufgelöst wird.
(Schalten Sie das Übersetzen oben auf dem Bildschirm aus, wenn der Text unten chaotisch ist.)
// Zuerst brauchen wir Container, die von 1 bis NJOBS indiziert werden können
// und enthält die Verweise auf die Datentabellen und die RunPrograms.
datatab = Assoziatives Array();
runprog = Assoziatives Array ();
who = {"jmp.com", "google.com", "bing.com"}; // jedes runProgram kann etwas anderes machen
NJOBS = N Artikel ( wer );
// Als nächstes eine Schleife, um Tabellen zu erstellen und die RunPrograms zu starten
Für( iJOB = 1, iJOB <= NJOBS, iJOB++,
// eine Tabelle mit einer Textspalte erstellen, dann die Spalte breit machen, damit wir mehr Daten sehen können
datatab[iJOB] = New Table( who[iJOB], addrows( 1 ), New Column( "text", Character, Set Values( {"pinging..."} ) ) );
datatab[iJOB]:text << setdisplaywidth( 500 );
// RunProgram starten.Es ist besonders wichtig, darauf zu achten, dass das RunProgram
// Das Objekt wird in einer Variablen gespeichert, die nicht überschrieben wird ... das assoziative Array enthält es.
runprog[iJOB] = Eval(
Auswertungsausdruck(
Programm ausführen (
Executable( "PING.EXE" ), // Dies ist der 'Job', von dem wir mehrere Kopien parallel ausführen
Options( {"-n 10", Expr( who[iJOB] )} ), // 10 Sekunden lang ausführen --- dies ist eine PING-Option
// nicht in JMP 11: Parameter( iJOB ), // merken, welche "Instanz" das ist --- das geht an die ReadFunction
ReadFunction( // Definiere eine Funktion, die für viele kleine Textschnipsel aufgerufen wird
Function( {this/* not in JMP 11: , myInstance*/}, // myInstance ist der iJOB
{Puffer = "",
// der JMP 11-Weg...
myInstance = Expr( iJOB ) // evalexpr kümmert sich darum
}, // lokal für diese Instanz. kleine Schnipsel puffern
While( this << canread, // this liest mehrere Snippets, die in einem einzigen Aufruf angezeigt werden können
Puffer = Puffer || (dies << lesen); // Füge die Schnipsel zusammen
Warte( .01 ); // Dies wird nicht wirklich benötigt, außer um die Snippets in einem einzigen Datensatz zu erhalten
); // sammle so viel wie möglich
Puffer = Regex( Puffer, "\s+", " ", GLOBALREPLACE ); // Bereinigen Sie den Puffer, entfernen Sie CRs und LFs
If( Trim( buffer ) != "", // sehen, ob wir etwas zu sagen haben.Es gibt Leerzeichen in der Ausgabe von PING
(datatab[meineInstanz]) << addrow( 1 ); // meine Tabelle bekommt eine neue Zeile
(datatab[meineInstanz]):text = Puffer; // Speichere den bereinigten Puffer
);
)
)
)
)
);
);
// Wenn Sie möchten, können Sie auf die Ausführungsprogramme warten.Sie *erfordern*, dass JMP untätig ist, um es zu machen
// der Rückruf an die Lesefunktion; die folgende Polling-Schleife verwendet wait(.1), um sicherzugehen
// JMP ist meistens im Leerlauf.Wenn das PING-Programm beendet wird, schließt es die STDOUT-Dateizugriffsnummer
// JMP hört zu, was dazu führt, dass die isReadEof-Nachricht TRUE zurückgibt.
Für( iJOB = 1, iJOB <= NJOBS, iJOB++,
While( !((runprog[iJOB]) << isReadEof), Wait( .1 ) )
);
Write( "Alles erledigt!\!n" ); // Jetzt können Sie mit den Datentabellen fortfahren
Danke vielmals!
Vielleicht offensichtlich für diejenigen, die dies tatsächlich verwenden würden, aber auf einem Mac würden Sie Folgendes benötigen:
Ausführbar( "/sbin/ping" ),
Optionen( { "-c 10" , wer[iJOB]} ),