Beispiellösung

Content

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <afblib/outbuf_printf.h>

/* function to be executed by a worker,
   where id is an integer in [0, # workers)
   and fd the writing end of the pipeline */
typedef void (*JobHandler)(unsigned int id, int fd);

typedef struct Worker {
   pid_t pid;
   int fd; /* reading end of the pipeline */
} Worker;

bool spawn_workers(Worker workers[], unsigned int number_of_workers,
      JobHandler handler) {
   for (unsigned int i = 0; i < number_of_workers; ++i) {
      int pipefds[2];
      if (pipe(pipefds) < 0) return false;
      pid_t child = fork();
      if (child < 0) return false;
      if (child == 0) {
	 close(pipefds[0]);
	 for (unsigned int j = 0; j < i; ++j) {
	    close(workers[i].fd);
	 }
	 handler(i, pipefds[1]);
	 exit(0);
      }
      close(pipefds[1]);
      workers[i] = (Worker) {
	 .pid = child,
	 .fd = pipefds[0],
      };
   }
   return true;
}

void do_sth(unsigned int id, int fd) {
   outbuf out = {fd};
   outbuf_printf(&out, "Greetings from worker %u!\n", id);
   outbuf_flush(&out);
}

bool copy(int in, int out) {
   char buf[8192];
   ssize_t nbytes;
   while ((nbytes = read(in, buf, sizeof buf)) > 0) {
      ssize_t written = 0;
      while (written < nbytes) {
	 ssize_t count = write(out, buf + written, nbytes - written);
	 if (count <= 0) return false;
	 written += count;
      }
   }
   return nbytes == 0;
}

#define WORKERS (10)

int main() {
   Worker workers[WORKERS];
   if (!spawn_workers(workers, WORKERS, do_sth)) {
      perror("spawn_workers"); exit(1);
   }
   for (unsigned int i = 0; i < WORKERS; ++i) {
      copy(workers[i].fd, 1); close(workers[i].fd);
      int wstat; waitpid(workers[i].pid, &wstat, 0);
   }
}
theon$ gcc -Wall -o fork-and-join fork-and-join.c -lafb -lowfat
fork-and-join.c:6:10: fatal error: afblib/outbuf_printf.h: No such file or directory
    6 | #include <afblib/outbuf_printf.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
theon$ ./fork-and-join
Greetings from worker 0!
Greetings from worker 1!
Greetings from worker 2!
Greetings from worker 3!
Greetings from worker 4!
Greetings from worker 5!
Greetings from worker 6!
Greetings from worker 7!
Greetings from worker 8!
Greetings from worker 9!
theon$