Pipes and COPY-ON-WRITE
In this example, every forked process gets its own copy of the
countervariable i through copy-on-write.
committer: Markus Bröker <mbroeker@largo.homelinux.org>
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
CC = gcc -g -ggdb $(PROF)
CPP = g++ -g -ggdb $(PROF)
- CFLAGS = -Wall -O2 -Iinclude -ansi
+ CFLAGS = -Wall -O2 -Iinclude #-ansi
RM = rm -f
FIND = find
@@ -67,6 +67,7 @@
TARGET += numbers
TARGET += nearest
TARGET += cppdatabase
+TARGET += pipe
.SUFFIXES: .c .cc .asm
@@ -322,6 +323,11 @@
@echo Linking $<...
@$(CPP) -Wall -O2 -g -ggdb $< -o $@
+pipe: pipe.o
+ @echo Linking $<...
+ @$(CC) -Wall -O2 -g -ggdb $< -o $@
+
+
.PHONY: beauty clean uninstall
clean:
new file mode 100644
--- /dev/null
+++ b/pipe.c
@@ -0,0 +1,69 @@
+/**
+ * pipe.c
+ * Copyright (C) 2009 Markus Broeker
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <wait.h>
+#include <assert.h>
+
+#define MAX 50
+
+int main (int argc, char **argv)
+{
+ int tube[2];
+ int i, status, count = 0;
+
+ pid_t pid;
+
+ char buffer[80];
+
+ for (i = 0; i < MAX; i++) {
+ if (pipe (tube) == -1) {
+ perror ("PIPE");
+
+ return EXIT_FAILURE;
+ }
+
+ pid = fork ();
+ switch (pid) {
+ case 0:
+ // we only want to write
+ close (tube[0]);
+
+ /**
+ * copy on write: every forked process gets its own copy of i
+ * and the magic of synchronization works
+ */
+ for (i = 0; i < MAX; i++)
+ status = write (tube[1], "MESSAGE FROM SON\n", 17);
+ break;
+
+ case -1:
+ printf ("ERROR");
+ break;
+
+ default:
+ printf ("Son started as pid %d\n", pid);
+
+ // we only want to read...
+ close (tube[1]);
+
+ FILE *f = fdopen (tube[0], "r");
+ assert (f != NULL);
+ while (fgets (buffer, sizeof (buffer), f) != NULL) {
+ printf ("FATHER RECEIVED [%4d]: %s", count++, buffer);
+ }
+
+ if (fclose (f) < 0)
+ perror ("fclose");
+
+ printf ("PID [%4d] has finished...\n", wait (&pid));
+ }
+ }
+
+ return EXIT_SUCCESS;
+}