2016-12-08 14 views
0

Also versuche ich ein Programm zu erstellen, das Benutzereingaben akzeptiert (Preis für Beispiel 50) und dann das erste Kind es an zweite, zweite eine 10 (Preis ist jetzt 60), dritte eins weitergibt dann 50 (Preis ist jetzt 110) und 4 man druckt nur/gibt den Endpreis zurück. Ich habe Fork in Loop und ich erstelle Rohre, aber der Preis ist immer der gleiche, nur 10 wird in jedem Kind hinzugefügt. Was ist falsch oder wie repariere ich das, damit es so funktioniert wie ich es möchte?C unbenannte Rohre und Gabel zur Berechnung

Mein Code:

int main(int argc,char *argv[]) 
{ 
int anon_pipe[2]; 
int n,N=4; 
char value_price[100]; 

if(argc>1) 
{ 
    int price=atoi(argv[1]); 
    printf("%d\n",price); 
    if(pipe(anon_pipe)==-1){ 
     perror("Error opening pipe"); 
     return -1; 
    } 
    for(n = 0; n < N; n++){ 
     switch(fork()){ 
      case -1: 
       perror("Problem calling fork"); 
       return -1; 
      case 0: 
       close(anon_pipe[1]); 

       read(anon_pipe[0],value_price,100); 

       price+=10; 

       sprintf(value_price,"%d \n",price); 
       printf("Price: %d\n",atoi(value_price)); 

       write(anon_pipe[1],value_price,sizeof(value_price)); 

       _exit(0); 
     } 
    } 
    close(anon_pipe[0]); 
    sleep(1); 
    close(anon_pipe[1]); 
} 

return 0; 
} 
+0

Beachten Sie, dass wir [Dokumentation] (http: // stackoverflow.com/documentation/posix/8082/pipes/26063/connecting-two-kind-processes-via-a-pipe # t = 201612081850028838105) zum Einrichten der Kind-Kind-Datenübertragung über eine Pipe. –

Antwort

1

Sie scheinen, dass Forking zu denken, das Kind Anfang vom Anfang des Programms macht. Dies ist nicht der Fall, Forking das Kind auf der gleichen Linie starten macht, wenn die fork() hier an diesem Code suchen

Zum Beispiel genannt wurde:

  read(anon_pipe[0],value_price,100); 

      price+=10; 

      sprintf(value_price,"%d \n",price); 
      printf("Price: %d\n",atoi(value_price)); 

Sehen Sie den Wert price erhöhen, aber Sie nie lesen dieser Wert bildet das Rohr. So geben alle Kinder immer +10 an ihre jeweilige Pipe aus.

0

Sie sollten die Rückgabewerte Ihrer Funktionsaufrufe auf Fehlercodes überprüfen. Wenn Sie getan hatte, würden Sie den Fehler aus dieser Kombination von Anrufen entstehen, erkannt haben:

  close(anon_pipe[1]); 

      // ... 

      write(anon_pipe[1],value_price,sizeof(value_price)); 

Sehr wahrscheinlich würden Sie auch festgestellt, dass viele dieser Anrufe ...

  read(anon_pipe[0],value_price,100); 

.. Signal Ende der Datei, ohne etwas zu lesen. Zumindest benötigen Sie den Rückgabewert read(), um zu bestimmen, wo der erforderliche Zeichenfolgenabschlusszeichen platziert werden soll (den Sie nicht platzieren können, bevor Sie den Puffer als Zeichenfolge verwenden).

Als allgemeine Regel ist es Pflicht die Rückgabewerte von read() und write(), denn neben der Möglichkeit, Fehler zu behandeln/EOF können diese Funktionen kurze Datenübertragungen statt Vollen zuführen. Der Rückgabewert gibt an, wie viele Bytes übertragen wurden. Sie müssen wissen, ob eine Schleife ausgeführt werden soll, um weitere Bytes zu übertragen.

Darüber hinaus haben Sie alle Ihre Prozesse verwenden die gleiche Rohrleitung miteinander zu kommunizieren. Sie könnten in diese Arbeit Glück haben, aber es ist wahrscheinlich, dass Sie zumindest manchmal mit einer verstümmelten Kommunikation enden. Sie sollten wirklich eine separate Pipe für jedes Paar kommunizierender Prozesse (einschließlich des übergeordneten Prozesses) erstellen.

Verwenden Sie außerdem nicht sleep(), um Prozesse zu synchronisieren. Es funktioniert nicht zuverlässig. Stattdessen sollte das übergeordnete Objekt wait() oder waitpid() für jeden seiner untergeordneten Prozesse sein, aber erst, nachdem sie alle gestartet wurden und die gesamte erforderliche Pipe-End-Verarbeitung durchgeführt wurde. Das Warten auf die Child-Prozesse verhindert auch, dass sie nach dem Verlassen der Zombies für längere Zeit unbenutzt bleiben. Das ist nicht so wichtig, wenn der Hauptprozess beendet wird, anstatt zu irgendeiner anderen Arbeit zu gehen, wie in diesem Fall, aber ansonsten stellt er ein Ressourcenleck (Dateideskriptoren) dar. Sie sollten die gute Angewohnheit bilden, auf Ihre Kindprozesse zu warten.

Natürlich ist das alles egal, wenn Sie nicht wirklich die Daten schreiben, die Sie schreiben wollen; @SanchkeDellowar erklärt in seiner Antwort, wie Sie das nicht schaffen.