This module manages m processes (scripts and executables). It can start and stop, and show and hide processes. It also supports a simple inter-process communication (IPC) mechanism via unidirectional named pipes, and an argument string.
Processes are identified by the name of their script or executable (without path and extension). Since shell processes do not have an associated script and thus no name, they cannot be managed from other processes. For instance, the script c:\documents\mShell\BTScanner.m has an associated process with name BTScanner. Process names are not case sensitive.
Get the argument string specified when the process was started via proc.run. For processes started manually from the process list or via the autostart feature, proc.arg returns the empty string.
|
// print the command line argument print proc.arg() → hello
|
With one argument, closes the process with the given name. Without an argument, closes the process it is called from.
Closing a process also stops it if it is running. If the process is already closed, or there is no such process, the call is ignored.
|
// stop and close the BTScanner process proc.close("BTScanner") |
Gets a list of all known scripts or executables in the current document folder whose name matches name. name is not case sensitive and can contain the wildcards * (matches any sequence of characters) and ? (matches any single character).
Throws ErrNotSupported when called from standalone applications.
|
// start all processes which end on "Test" for f in proc.find("*Test") do proc.run(f) end |
With one argument, hides the process with the given name. Without an argument, hides the process it is called from.
In the mShell application, this call simply shows the list of scripts and modules. In standalone applications, this call hides the application.
If the process is not currently shown, this call does nothing.
Throws ErrNotFound if there is no running process with the given name.
|
// hide the current process proc.hide() |
Opens or creates a pipe with name name and returns a stream to read from and write to the pipe. The pipe can be opened by other processes using the same name, thus providing a communication channel between m processes.
If create=false, the function throws ErrNotFound if the pipe does not already exist.
If created, the pipe will have a buffer of bufsize bytes. The default size is large enough for efficient inter-process communication (IPC): whenever there is not enough room in the pipe buffer, a write to the pipe will block until another process reads from the pipe to free up space.
However, if the same process reads from and writes to the pipe, the buffer must be large enough to hold all data written between reads. This is the only case where larger buffer sizes may be needed.
Once created, a pipe stream is accessed via module io:
Only one process can read from the pipe at a given time. Issuing a read with another read pending (from another process) will throw ErrInUse.
Up to sixteen processes can write to the pipe at a given time. Issuing a write when sixteen other writes are pending (from other processes) will throw ErrNotReady.
Pipes are unidirectional. For bidirectional communication between processes, two pipes (with different names) are required.
The first trivial example just shows how to read from and write to a pipe:
|
// create a pipe stream and write to it s=proc.pipe("SamplePipe"); io.writeln(s, "Hello world!"); // read from the pipe what was written into it print io.readln(s) → Hello world!
// close the stream; this will also delete the pipeio.close(s) |
A more realistic example consists of two processes with two pipes. The first process in script Reverser reads a line from pipe ReverserIn, and writes the reversed line to pipe ReverserOut:
|
function reverse(s) c=code(s); i=0; j=len(c)-1; while i<j do h=c[i]; c[i]=c[j]; c[j]=h; i++; j-- end; return char(c) end // create (or open) the two pipes rin=proc.pipe("ReverserIn"); rout=proc.pipe("ReverserOut"); // loop forever reading, reversing and writing while true do io.writeln(rout, reverse(io.readln(rin))) end |
We now can use the reverser process:
|
// make sure the reverser runs proc.run("Reverser"); rin=proc.pipe("ReverserIn"); rout=proc.pipe("ReverserOut"); io.writeln(rin,"Hello world!"); print io.readln(rout) → !dlrow olleH
|
Runs (starts) the process with the given name, and the argument string arg. If a process with this name is already running, the call is ignored.
name is always relative to the "document" directory of the current process (system.docdir). If there is an executable (.mex file) with the given name, it will be loaded. Otherwise, the script (.m file) will be loaded.
The argument string is accessed via proc.arg from the target process.
Throws ErrNotFound if there is no executable or script with the given name.
|
// start the BTScanner process, passing "hello" to it proc.run("BTScanner", "hello") |
Returns true if the process with the given name is running, and false if it is stopped, or there is no such process.
Throws ErrNotFound if there is no executable or script with the given name.
|
// stop the BTScanner process proc.stop("BTScanner"); // it should not be running now proc.runs("BTScanner") → false
|
With one argument, shows the process with the given name. Without an argument, shows the process it is called from.
Showing a process shows its console, or any other view it is displaying. If the process is already shown, the call is ignored.
Throws ErrNotFound if there is no running process with the given name.
|
// show the current process proc.show() |
With one argument, stops the process with the given name. Without an argument, stops the process it is called from, i.e. terminates it.
If the process is not running, the call is ignored.
|
// stop the current process proc.stop() |