17.6 Sequential Tasks

Team-FLY

17.6 Sequential Tasks

This section describes the behavior of the dispatcher when the child task has both input and output. Although the dispatcher handles only one task at a time, it must monitor two input file descriptors. Complete Section 17.5 before starting this part.

The dispatcher keeps information about the child task in the tasks array. For simplicity, the discussion refers to members of the ntpvm_task_t array such as readfd without their qualifying structure. Implement the tasks array as an object with appropriate access functions. The tasks array and its access functions should be in a file separate from the dispatcher main program. The array and its access functions are referred to as the tasks object, and an individual element of the tasks array is referred to as an entry of the tasks object. For this part, we only allow one task at a time, so the tasks object does not need an array of tasks.

Figure 17.8 suggests the structure of threaded NTPVM dispatcher. An input thread monitors standard input and processes the incoming packets. An output thread monitors the readfd descriptor for input from the child task and writes this information to standard output.

Figure 17.8. Schematic of a threaded NTPVM dispatcher for a single task.

graphics/17fig08.gif

The input and output threads share the tasks object and must synchronize their access to this structure. One possible approach for synchronizing threads is to use a mutex lock to protect the entire tasks object. This choice cuts down on the potential parallelism because only one thread at a time can access the tasks object. Since mutex locks are low cost, we use a mutex lock for each element of the tasks array.

17.6.1 The input thread

The input thread monitors standard input and takes action according to the input it receives. Write an input function that executes the following steps in a loop until it encounters an end-of-file on standard input.

  1. Read a packet from standard input by using getpacket .

  2. Process the packet.

After falling through the loop, close writefd and call pthread_exit .

Processing a packet depends on the packet type.

 NEWTASK 
  1. If a child task is already executing, discard the packet and output an error message.

  2. Otherwise, if no child task exists, create two pipes to handle the task's input and output.

  3. Update the tasks object, and fork a child. The child should redirect its standard input and output to the pipes and use the makeargv function of Program 2.2 to construct the argument array before calling execvp to execute the command given in the packet.

  4. Create a detached output thread by calling pthread_create . Pass a key for the tasks entry of this task as an argument to the output thread. The key is just the index of the appropriate tasks array entry.

 DATA 
  1. If the packet's communication and task IDs don't match those of the executing task or if the task's endinput is true, output an error message and discard the packet.

  2. Otherwise, copy the data portion to writefd .

  3. Update the recvpackets and recvbytes members of the appropriate task entry of the tasks object.

 DONE 
  1. If the packet's computation and task IDs do not match those of the executing task, output an error message and discard the packet.

  2. Otherwise, close the writefd descriptor if it is still open .

  3. Set the endinput member for this task entry.

BROADCAST , BARRIER or TERMINATE

  1. Output an error message.

  2. Discard the packet.

Exercise 17.9

When a process that contains multiple threads creates a child by calling fork , how many threads exist in the child?

Answer:

Although fork creates a copy of the process, the child does not inherit the threads of the parent. POSIX specifies that the child has only one thread of executionthe thread that called fork .

17.6.2 The output thread

The output thread handles input from the readfd descriptor of a particular task. The output thread receives a tasks object key to the task it monitors as a parameter. Write an output function that executes the following steps in a loop until it encounters an end-of-file on readfd .

  1. Read data from readfd .

  2. Call putpacket to construct a DATA packet and send it to standard output.

  3. Update the sentpackets and sentbytes members of the appropriate task entry in the tasks object.

After falling through the loop because of an end-of-file or an error on readfd , the output thread does the following.

  1. Close the readfd and writefd descriptors for the task.

  2. Execute wait for the child task.

  3. Send a DONE packet with the appropriate computation and task IDs to standard output.

  4. Output information about the finished task to standard error or to the remote logger. Include the computation ID, the task ID, the total bytes sent by the task, the total packets sent by the task, the total bytes received by the task and the total packets received by the task.

  5. Deactivate the task entry by setting the computation ID to

  6. Call pthread_exit .

Test the program by starting tasks to execute various cat and ls -l commands. Try other filters such as sort to test the command-line parsing. For this part you should not enter a new command until the previous command has completed.

Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net