Navigationskarta Insitutitionen för Datavetenskap Umeå Universitet

Uppgifter och lösningar från gruppövning 4 (99-10-07)


1. Många program innehåller kritiska kodavsnitt som inte får avbrytas av signaler. Skriv två funktioner, sig_block och sig_unblock, som blockerar alla signaler respektive återställer signalblockeringen till sin föregående inställning. Skriv också ett huvu dprogram som kan användas för att testa att funktionerna fungerar.

2. Skriv ett program som skapar två barn och två pipor. Den ena pipan kopplar ihop det första och det andra barnet och den andra pipan ligger mellan andra barnet och föräldern. Det första barnet ska skicka en sträng (t ex "Child 1" ) till andra barnet via stdout (första pipan). Det andra barnet ska läsa via stdin (första pipan) och skriva till stdout (andra pipan). Dvs det andra barnet ska både skicka vidare datat som läses från den första pipan samt en egen textrad (t ex "Child 2") Förälderna ska sedan läsa från stdin (andra pipan) och skriva ut på stdout. Eftersom alla processer bara ska arbeta mot stdout och stdin är omdirigering av fildeskriptorerna STDIN_FILENO och STDOUT_FILENO nödvändig. Resultatet av att köra programmet kan se ut någonting liknande:

Parent here
Child 1 
Child 2

En enkel skiss över strukuren av processer och pipor ser ut enligt:
        Pipa 1     Pipa 2
         /  \       /  \
        /    \     /    \
    Barn 1    Barn 2    Förälder



#include <signal.h> #include <stdio.h> #include <unistd.h> sigset_t bsig; /* Blocked signals */ void die_p(const char *s) { perror(s); exit(1); } void sig_block(void) { sigset_t asig; /* All signals */ if (sigfillset(&asig) == -1) die_p("sigfillset"); if (sigprocmask(SIG_SETMASK, &asig, &bsig) == -1) die_p("sigprocmask"); } void sig_unblock(void) { if (sigprocmask(SIG_SETMASK, &bsig, NULL) == -1) die_p("sigprocmask"); } int main(void) { sig_block(); puts("All signals blocked"); sleep(5); sig_unblock(); puts("Signal mask restored"); sleep(5); return 0; }

Ovanstående kod är lösningen till uppgift 1.


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

void closePipes(int pipes[][2], int numberOfPipes);

int main (void) { 
  int pipes[2][2], i;
  pid_t pid;
  char line[256];
  
  pipe(pipes[0]);
  pipe(pipes[1]);

  for(i=0;i<2;i++) {
    pid = fork();

    if(pid==0) {      
      dup2(pipes[i][1],STDOUT_FILENO);
      if(i==1) {
        dup2(pipes[0][0], STDIN_FILENO);
        closePipes(pipes,2);
        gets(line);
        printf("%s\n%s\n",line,"Child 2 here");
      }
      else {	
        closePipes(pipes,2);
        printf("Child 1 here\n");
      }
      return 0;
    }
  }

  dup2(pipes[1][0], STDIN_FILENO);
  closePipes(pipes,2);
  printf("Output from parent:\n");
  while(gets(line))
    puts(line);


  return 0;
}  

void closePipes(int pipes[][2], int numberOfPipes)
{
  int i,j;

  for(i=0;i<numberOfPipes;i++)
    for(j=0;j<2;j++)
      close(pipes[i][j]);
}

Ovanstående kod är lösningen till uppgift 2.

[an error occurred while processing this directive]