Standard Input and Output<A NAME=1480> </A>



next up previous contents index
Next: Tracing Up: Task Environment Previous: Environment Variables

Standard Input and Output 

 

Each task spawned through PVM has /dev/null opened for stdin. From its parent, it inherits a stdout sink, which is a (TID, code) pair. Output on stdout or stderr is read by the pvmd through a pipe, packed into PVM messages and sent to the TID, with message tag equal to the code. If the output TID is set to zero (the default for a task with no parent), the messages go to the master pvmd, where they are written on its error log.

Children spawned by a task inherit its stdout sink. Before the spawn, the parent can use pvm_setopt() to alter the output TID or code. This doesn't affect where the output of the parent task itself goes. A task may set output TID to one of three settings: the value inherited from its parent, its own TID, or zero. It can set output code only if output TID is set to its own TID. This means that output can't be assigned to an arbitrary task.

Four types of messages are sent to an stdout sink. The message body formats for each type are as follows:

------------------------------------------------------------
Spawn:     (code) {                  Task has been spawned
                      int tid,       Task id
                      int -1,        Signals spawn
                      int ptid       TID of parent
                  }

Begin:     (code) {                  First output from task
                      int tid,       Task id
                      int -2,        Signals task creation
                      int ptid       TID of parent
                  }

Output:    (code) {                  Output from a task
                      int tid,       Task id
                      int count,     Length of output fragment
                      data[count]    Output fragment
                  }

End:       (code) {                  Last output from a task
                      int tid,       Task id
                      int 0          Signals EOF
                  }
------------------------------------------------------------

The first two items in the message body are always the task id and output count, which allow the receiver to distinguish between different tasks and the four message types. For each task, one message each of types Spawn, Begin, and End is sent, along with zero or more messages of class Output, (count > 0). Classes Begin, Output and End will be received in order, as they originate from the same source (the pvmd of the target task). Class Spawn originates at the (possibly different) pvmd of the parent task, so it can be received in any order relative to the others. The output sink is expected to understand the different types of messages and use them to know when to stop listening for output from a task (EOF) or group of tasks (global EOF).

The messages are designed so as to prevent race conditions when a task spawns another task, then immediately exits. The output sink might get the End message from the parent task and decide the group is finished, only to receive more output later from the child task. According to these rules, the Spawn message for the second task must arrive before the End message from the first task. The Begin message itself is necessary because the Spawn message for a task may arrive after the End message for the same task. The state transitions of a task as observed by the receiver of the output messages are shown in Figure gif.

  
Figure: Output states of a task

The libpvm function pvm_catchout() uses this output collection feature to put the output from children of a task into a file (for example, its own stdout). It sets output TID to its own task id, and the output code to control message TC_OUTPUT. Output from children and grandchildren tasks is collected by the pvmds and sent to the task, where it is received by pvmmctl() and printed by pvmclaimo().



next up previous contents index
Next: Tracing Up: Task Environment Previous: Environment Variables