cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
Submit your abstract to the call for content for Discovery Summit Americas by April 23. Selected abstracts will be presented at Discovery Summit, Oct. 21- 24.
Craige_Hales
Super User
RunProgram

update 27apr2018: repair formatting

 

Just got a question about using multiple RunProgram instances at the same time.  Here's an example that runs three copies of PING against three different IP addresses and records the results in three different data tables.  The example shows how to use the "parameter" value to make each RunProgram know which data table to use.  Attachment is same as 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

There is a limit to how many of these you can run at once.  Probably not hundreds; they uses resources on your computer that are not unlimited.

Last Modified: Apr 27, 2018 10:36 AM
Comments