Webseiten Navigation: Airbit | Shop | m-shell.net
Sprachen: EN | DE

Module proc: m Processes

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.

proc.arg

• function arg() → String

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

proc.close

• function close(name) → null
• function close() → null

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")

proc.find

• function find(name="*") → Array

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

proc.hide

• function hide(name) → null
• function hide() → null

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()

proc.pipe

• function pipe(name, create=true, bufsize=256) → Native Object

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:

  • io.read, io.readln, and io.readm read data,
  • io.write, io.writeln, io.writem, io.print, and io.println write data,
  • io.avail gets the number of bytes which can be read without blocking,
  • io.wait waits for data which can be read without blocking,
  • io.close closes the stream (but not the pipe). The pipe will be deleted when all streams referencing it have been closed.
  • io.ces gets and sets the character encoding scheme. As with files, the default is io.raw.
  • io.timeout sets the timeout for read and write operations.
  • io.flush sets the auto flush state. If auto flushing is disabled, io.flush must be called to make sure all data is written.
With io.readm and io.writem are ideally suited for pipes, as data is both written and read by m.

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 pipe
io.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

proc.run

• function run(name, arg="") → null

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")

proc.runs

• function runs(name) → Boolean

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

proc.show

• function show(name) → null
• function show() → null

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()

proc.stop

• function stop(name) → null
• function stop() → null

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()


© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-LIB-888
mShell Home  > Dokumentation  > Manuals