2016-04-14 9 views
0

Ich soll ein Programm schreiben, die 2 Prozesse erstellt, verbindet sie mit einer Leitung, und nach einer bestimmten Zeit wird beide Prozesse beenden und zu beenden . Eines der Programme schreibt in die Pipe, und das andere liest daraus und druckt es auf STDOUT. der Lesevorgang wird zuerst aufgerufen, dann wird die PID an den zweiten Prozess übergeben, so dass es dem ersten Prozess SIGUSR1-Signale gibt, um es zu lesen. aus irgendeinem Grund sehe ich nie die Ausgabe im Terminal des ersten Prozesses, weiter mehr, es druckt nicht einmal die Zeile: "versuchen, exec1 \ n", wo ich "execlp" für den Prozess, der druckt . hier ist der Code für die drei Programme:Die Ausgabe des Programms im Terminal nicht nach der Verwendung von Gabel und Rohr in c

das Hauptprogramm:

#define STDERR 2 
#define STDOUT 1 
#define STDIN 0 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <signal.h> 
#include <stdio.h> 
void alarmHandler(int sig); 
void systemError(); 

char * intToString(int num , char number[4]); 

static pid_t processId1, processId2; 

int main(int argc, char ** argv){ 
    pid_t pid1, pid2; 
    sigset_t block_mask1; 
    struct sigaction exitSig; 
    sigfillset(&block_mask1); 
    exitSig.sa_handler = alarmHandler; 
    exitSig.sa_mask = block_mask1; 
    exitSig.sa_flags = 0; 
    sigaction(SIGALRM, &exitSig, NULL); 
    if (argc < 2){ 
      systemError(); 
    } else { 
     int x = atoi(argv[1]); 
     alarm(x); 
    } 
    int fields[2]; 
    if (pipe(fields)){ 
     systemError(); 
    } 

    if ((pid1 = fork()) == 0){ 
     printf("trying to exec1\n"); 
     close(STDIN); 
     dup(fields[0]); 
     close(fields[0]); 
     close(fields[1]); 
     if(execlp("./ex2_inp", "./ex2_inp", NULL)){ 
      systemError(); 
     } 
    } else { 
     processId1 = pid1; 
     if ((pid2 = fork()) == 0){ 
      char number[350]; 
      printf("trying to exec2\n"); 
      close(STDOUT); 
      dup(fields[1]); 
      close(fields[0]); 
      close(fields[1]); 
      char * pidString = intToString(processId1, number); 
      if(execlp("./ex2_upd","./ex2_upd",pidString, NULL)){ 
       systemError(); 
      } 
     } else{ 
      processId2 = pid2; 
     } 
    } 

    close(fields[0]); 
    close(fields[1]); 
    pause(); 
    return 1; 
} 

/*********************** 
* handler for alarm signal 
*************************/ 
void alarmHandler(int sig){ 
    kill(processId2, SIGINT); 
    kill(processId1, SIGINT); 
    exit(1); 
} 

/*********************** 
* turn pid to string 
*************************/ 
char * intToString(int num , char number[350]){ 
    sprintf(number, "%d", num); 
    return number; 
} 

ex2_inp:

#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <signal.h> 
#include <stdio.h> 
void exitHandler(int sig); 
void printHandler(int sig); 
int main(int argc, char * argv[]){ 

    sigset_t block_mask1, block_mask2; 
    struct sigaction exitSig, print; 
    sigfillset(&block_mask1); 
    sigfillset(&block_mask2); 
    exitSig.sa_handler = exitHandler; 
    print.sa_handler = printHandler; 
    print.sa_mask = block_mask2; 
    exitSig.sa_mask = block_mask1; 
    exitSig.sa_flags = 0; 
    print.sa_flags = 0; 
    sigaction(SIGINT, &exitSig, NULL); 
    sigaction(SIGUSR1, &print, NULL); 
    pause(); 
    return 1; 
} 

void exitHandler(int sig){ 
    printf("exiting1!\n"); 
    close(1); 
    exit(1); 
} 

void printHandler(int sig){ 
    char * buffer[80]; 
    read(1, buffer, 80); 
    printf("%s", buffer); 
} 

ex2_upd:

#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <signal.h> 
#include <stdio.h> 
void exitHandler(int sig); 

int main(int argc, char * argv[]){ 
    sigset_t block_mask1; 
    struct sigaction exitSig; 
    sigfillset(&block_mask1); 
    exitSig.sa_handler = exitHandler; 
    exitSig.sa_mask = block_mask1; 
    exitSig.sa_flags = 0; 
    sigaction(SIGINT, &exitSig, NULL); 
    printf("2's message\n"); 
    kill(atoi(argv[1]), SIGUSR1); 
    pause(); 
    return 1; 
} 

void exitHandler(int sig){ 
    printf("exiting2!\n"); 
    close(0); 
    exit(1); 
} 

dank

+0

Versuchen Sie es mit 'fflush (stdout);' nach dem Aufruf von 'printf' und vor dem Aufruf von' close' um sicherzustellen, was passiert ist ' printf' wird gedruckt. – MikeCAT

+0

es hilft nicht, und ich sehe immer noch nicht die "2's message \ n", die ich bekommen soll, gedruckt durch den ersten Prozess – Ryan

+0

'printf()' ist nicht async-sicher. Auch die Art, wie Sie das Signal senden wollen, ist eine Race-Condition. Das Signal kann gesendet werden * bevor * der Empfänger 'sigaction()' aufgerufen hat. – EOF

Antwort

0

ex2_upd.c:

#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <signal.h> 
#include <stdio.h> 
void exitHandler(int sig); 

int main(int argc, char * argv[]){ 
    sigset_t block_mask1; 
    struct sigaction exitSig; 
    sigfillset(&block_mask1); 
    exitSig.sa_handler = exitHandler; 
    exitSig.sa_mask = block_mask1; 
    exitSig.sa_flags = 0; 
    sigaction(SIGINT, &exitSig, NULL); 
    printf("2's message\n"); 
    kill(atoi(argv[1]), SIGUSR1); 
    sleep(1); /* This was pause - causing ex2_inp read() to wait forever, since read() on pipe needs to either fill buffer or END_OF_FILE, unless we make the filedescriptor in the read-end non-blocking via fcntl() */ 
    return 1; 
} 

void exitHandler(int sig){ 
    printf("exiting2!\n"); 
    close(0); 
    exit(1); 
} 

ex2_inp.c:

#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <dirent.h> 
#include <signal.h> 
#include <stdio.h> 
void exitHandler(int sig); 
void printHandler(int sig); 
int main(int argc, char * argv[]){ 

    sigset_t block_mask1, block_mask2; 
    struct sigaction exitSig, print; 
    sigfillset(&block_mask1); 
    sigfillset(&block_mask2); 
    exitSig.sa_handler = exitHandler; 
    print.sa_handler = printHandler; 
    print.sa_mask = block_mask2; 
    exitSig.sa_mask = block_mask1; 
    exitSig.sa_flags = 0; 
    print.sa_flags = 0; 
    sigaction(SIGINT, &exitSig, NULL); 
    sigaction(SIGUSR1, &print, NULL); 
    pause(); 
    return 1; 
} 

void exitHandler(int sig){ 
    printf("exiting1!\n"); 
    close(1); 
    exit(1); 
} 

void printHandler(int sig){ 
    char buffer[80]; /* removed * */ 
    read(0, buffer, 80); /* stdin is fd=0, not 1 */ 
    printf("-> %s <-\n", buffer); /* added \n, forces new-line */ 
}