Navigationskarta Insitutitionen för Datavetenskap Umeå Universitet

Kodexempel F10

Låt mig än en gång påminna om att koden nedan saknar vissa elementära felkontroller (exempelvis av fork). Detta är av utrymmesskäl (ett OH-blad är ganska begränsat). Motsvarande kod kommer inte att accepteras på laborationerna.

Det finns några PostScript-bilder med fler exempel.


#include <stdio.h>
#include <unistd.h>

int main (void) {
  char line[128];
  int fd[2], n;

  if (pipe(fd) < 0) ... /* Något gick fel */

  write(fd[1], "test\n", 5);
  n = read(fd[0], line, 128);
  write(STDOUT_FILENO, line, n);
	
  return 0;
}

#include <stdio.h> #include <unistd.h> int main (void) { char line[128]; int fd[2], n; if (pipe(fd) < 0) ... if (fork() == 0) { /* Child */ close(fd[0]); write(fd[1], "test\n", 5); } else { /* Parent */ close(fd[1]); n = read(fd[0], line, 128); write(STDOUT_FILENO, line, n); } return 0; }
#include <stdio.h> #include <unistd.h> int main (void) { char line[128]; int fd[2]; if (pipe(fd) < 0) ... if (fork() == 0) { /* Child */ dup2(fd[1], STDOUT_FILENO); close(fd[0]); /* Stäng läsänden */ close(fd[1]); /* Nu har vi ju stdout */ printf("hej!\n"); fflush(stdout); sleep(3); printf("hej igen!\n"); } else { /* Parent */ dup2(fd[0], STDIN_FILENO); close(fd[1]); /* Stäng skrivänden */ close(fd[0]); /* Nu har vi ju stdin */ fgets(line, 128, stdin); printf("P till stdout: %s\n", line); fgets(line, 128, stdin); printf("P till stdout igen: %s\n", line); } return 0; }
#include <stdio.h> #include <unistd.h> int main (void) { char line[128]; int fd[2]; if (pipe(fd) < 0) ... if (fork() == 0) { /* Child */ dup2(fd[1], STDOUT_FILENO); close(fd[0]); /* Stäng läsänden */ close(fd[1]); /* Nu har vi ju stdout */ printf("C här!\n"); fflush (stdout); if (execl("/usr/bin/sh", "/usr/bin/sh", "-c", "ls", NULL) < 0) ... } else { /* Parent */ dup2(fd[0], STDIN_FILENO); close(fd[1]); /* Stäng skrivänden */ close(fd[0]); /* Nu har vi ju stdin */ while(fgets(line, 128, stdin) != NULL) printf("P fick från C: %s", line); } return 0; }
int main (void) { /* stdio, unistd fick inte plats... */ char line[128]; int fd[2]; if (pipe(fd) < 0) ... if (fork() == 0) { /* Child 1 */ dup2(fd[1], STDOUT_FILENO); close(fd[0]); /* Stäng läsänden */ close(fd[1]); /* Nu har vi ju stdout */ printf("C1 här!\n"); fflush (stdout); if (execl("/usr/bin/sh", "/usr/bin/sh", "-c", "ls", NULL) < 0)... } else { /* Parent */ if (fork() == 0) { /* Child 2 */ dup2(fd[0], STDIN_FILENO); close(fd[1]); /* Stäng skrivänden */ close(fd[0]); /* Nu har vi ju stdin */ while(fgets (line, 128, stdin) != NULL) printf("C2 fick från C1: %s", line); } else { /* Parent */ sleep(3); puts("Parent slutar!"); } } return 0; }
Programmet startar: USER RSS VSZ COMMAND gunnar 392 800 a.out Programmet allokerar 10 MB (malloc): USER RSS VSZ COMMAND gunnar 408 11048 a.out Programmet frigör 10 MB (free): USER RSS VSZ COMMAND gunnar 408 11048 a.out
Kommando för ovanstående mätningar:
ps -u gunnar -o user,rss,vsz,comm | egrep 'a.out|RSS'
Denna OH beskriver det intressanta fenomenet att free() inte lämnar tillbaka minnet till operativsystemet.

 % vmstat
 procs     memory            page            disk          faults      cpu
 r b w   swap  free  re  mf pi po fr de sr f0 s0 s6 --   in   sy   cs us sy id
 0 0 0   2912   160   0  24  3  0  0  0  0  0  1  0  0  233  356  155  8  4 88

procs: processtatistik (run/blocked/waiting)
memory: ledigt minne
page: sidoperationer per sekund (mp/po: kB in/ut)
disk: diskoperationer per sekund
faults: avbrott per sekund (IO/systemanrop/kontextbyten)
cpu: cpu-tid (user/system/idle)
[an error occurred while processing this directive]