Shared Memory --- Parallel filters and piping -- Examples Needed

Stuart D. Gathman stuart at bms-at.UUCP
Sat Feb 20 04:35:01 AEST 1988


>  From: "John S. Robinson" <jsrobin at eneevax.uucp>

> If a programmer has filters filt1, filt2, ... filtn which he wishes to
> apply in a serial fashion on a stream of data, the process can be accomplished
> in a trivial fashion by use of a sequence of pipes:
>   filt1 < <stream> |filt2 |filt3 | ... |filtn > <sink> .

>   How does one handle the case where some of the above filters are to be
>   applied in parallel and then be recombined:

Here is my solution:

filt1|cat `@ filt2` `@ filt3`|filt4

The '@' program executes its arguments ala 'nohup' or 'nice' with stdout
connected to a named pipe.  The name of the named pipe is printed on @'s
standard output (which is different from the program it runs).  Note that
this function cannot be written as a shell script because the shell insists
on waiting for all background processes before exiting.

/* @.c */
#include <stdio.h>
#include <fcntl.h>

static char null[] = "/dev/null";	/* null device in case of error */

main(argc, argv)
  char **argv;
{
  char *fname;
  int fd;

  fname = tempnam(NULL,"@pipe");
  if (argc < 2) {
    puts(null);
    return 1;
  }

  fd =  mknod(fname,0010600);
  if (fd == -1) {
    perror(fname);
    puts(null);
    return 1;
  }

  switch (fork()) {
  case 0:
    close(1);
    fd = open(fname,O_WRONLY);
    if (fd != 1) return 1;
    switch (fd = fork()) {
    case 0:
      execvp(argv[1],argv+1);	/* try to execute direct */
      perror(argv[1]);
      return 1;
    case -1:
      perror("fork");
      unlink(fname);
      return 1;
    default:
      while (wait((int *)0) != fd);
      unlink(fname);
      return 0;
    }
  case -1:
    perror("fork");
    puts(null);
    return 1;
  default:
    puts(fname);
  }
  return 0;
}
-- 
Stuart D. Gathman	<stuart at bms-at.uucp>
			<..!{vrdxhq|dgis}!bms-at!stuart>



More information about the Comp.unix.wizards mailing list