Snafu: C: Kindprozess ohne kill() / killpg() terminieren

Hallo!
Hab ein Problem das ich nicht so einfach lösen kann.
Ich hab einen Prozess, der mittels fork() einen Kindprozess erzeugt. Im Hauptprozess warte ich bis der Kindprozess fertig ist. Dauert das jedoch zu lange, so soll ich dem Hauptprozess ein Signal geben können (SIGINT z.B.) worauf anschließend der Kindprozess beendet wird (bzw. in einen Zustand gebracht wird wo er beenden kann).
Das beenden des Kindprozesses soll __ohne__ kill() oder killpg() erfolgen.

Der Kindprozess ruft selber wieder fork() auf und wiederholt dies so lange, bis dessen Kindprozess nicht mehr normal (Exitstatus 0) terminiert, sondern mit Exitstatus 1.

Die einzig mögliche Lösung, die mir einfällt, wäre, dass im Hauptprozess vor dem fork() ein shared memory angelegt wird und ein default-Wert eingetragen wird (z.B. 1). Kommt nun im Hauptprozess das Signal zum beenden des Kindprozesses, so ändere ich einfach das shared memory (z.B. auf 0).
Im Kindprozess wird die fork()-Geschichte ja in einer Schleife gemacht, jetzt einfach mit einer extra Bedingung.

---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---  
/* Kind vom Hauptprozess */  
int ret, childExit, pid;  
...  
do {  
    pid = fork();  
    ...  
    /* parent zweig */  
    while((ret = wait(&childExit)) != pid) {  
        if(ret == -1 || errno == EINTR)  
            continue;  
        _exit(1);  
    }  
} while(WEXITSTATUS(childExit) == 0 && shared_memory == 1);  
  
if(WEXITSTATUS(childExit) == 1)  
    _exit(0);  
_exit(1);  
...  
---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---

Das ist jedoch auch nicht das Gelbe vom Ei, da:
a) ich deswegen kein shared memory anlegen will
b) das irgendwie anders (ohne kill() / killpg()) gehen muss

Die fork()-Schleife vom Kindprozess kann ich nicht in den Hauptprozess verlagern, sie __muss__ im Kindprozess erfolgen.

Falls ihr euch fragt warum ich kein kill() / killpg() verwenden will, ich darf es nicht (Richtlinien Bsp 3, ganz unten).

Hoffe mir kann jemand helfen, ich bin mit meinem Latein am Ende.

--
LG,
Snafu
  1. Moin Moin!

    Falls ihr euch fragt warum ich kein kill() / killpg() verwenden will, ich darf es nicht (Richtlinien Bsp 3, ganz unten).

    Ui! Hausaufgaben! Vermutlich hast Du die Aufgabenstellung nicht richtig verstanden oder einen just vom Prof erklärten Kniff nicht verstanden.

    Die fork()-Orgie kommt mir jedenfalls sehr merkwürdig vor.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
    1. Hallo!

      Ui! Hausaufgaben!

      Auf der Universität heisst das Übungsbeispiel ;)
      Keine Angst, die Abgabe ist im Jänner. Ich werde also nicht herumspammen, dass mir endlich wer antworten soll :)

      Vermutlich hast Du die Aufgabenstellung nicht richtig verstanden oder einen just vom Prof erklärten Kniff nicht verstanden.

      Es gab keinen Tipp vom Prof und die Aufgabenstellung habe ich auch richtig verstanden. Der einzige "Tipp" ist der Verweis auf die Programmierrichtlinien.

      Die fork()-Orgie kommt mir jedenfalls sehr merkwürdig vor.

      Mir auch, kann ich aber nichts daran ändern.
      Zitat Angabe: "... Das Programm schedule erzeugt einen Kindprozess, der zufällig irgendwann im spezifiziertem Zeitfenster (in s bis s+f Sekunden) das Programm program periodisch solange immer wieder ausfuehrt, bis program mit einem Fehlercode terminiert. ..."
      Das Programm erzeugt einen Kindprozess, der (Kindprozess) das Programm program periodisch solange immer wieder ausführt, bis program mit einem Fehlercode terminiert. Ich brauche also fork() und die fork()-Schleife.

      --
      LG,
      Snafu
  2. Hallo,

    ich hab mir Dein Problem jetzt nicht genau angesehen (es sieht ziemlich konfus aus und ich hab gerade Kopfschmerzen - vielleicht sehe ich mir das später nochmal genauer an), aber ich sehe im Prinzip drei Möglichkeiten:

    a) Du überrpüfst das Timeout im Kindprozess und nicht im Elternprozess und der Kindprozess beendet sich selbst. Weiß nicht, ob das mit Deiner Aufgabenstellung zusammenpasst, aber das wäre wohl das einfachste. Wenn Du im Zweifel noch Systemaufrufe unterbrechen willst, dann kannst Du Dir alarm(2) annsehen.

    b) Du nutzt eben kill() - das ist die einzige Möglichkeit, einem Prozess ein Signal zu senden (naja, außer über system("kill PID"), was aber im Endeffekt auf's gleiche hinausläuft ;-)).

    c) Du nutzt irgend einen IPC-Mechanismus wie Shared Memory, Semaphore oder eben sowas simples wie ne Pipe / ein Socketpaar, das vor dem Fork angelegt wird.

    Viele Grüße,
    Christian

    1. Hallo!

      ich hab mir Dein Problem jetzt nicht genau angesehen (es sieht ziemlich konfus aus und ich hab gerade Kopfschmerzen - vielleicht sehe ich mir das später nochmal genauer an).

      Kein Problem, geht mir bei manchen Sachen auch so :)
      Bezgl später anschauen, ich bitte darum.

      a) Du überrpüfst das Timeout im Kindprozess und nicht im Elternprozess und der Kindprozess beendet sich selbst. ...

      Ich verstehe nicht ganz was du mit Timeout überprüfen meinst.

      b) Du nutzt eben kill()

      Ja kill wäre natürlich optimal, das darf ich jedoch (frag mich nicht warum) nicht verwenden, siehe Programmierrichtlinien sofern dich interessiert wie eingeschränkt ich bin (vor allem zu Bsp 3 ganz unten) :)

      c) Du nutzt irgend einen IPC-Mechanismus wie Shared Memory, Semaphore oder eben sowas simples wie ne Pipe / ein Socketpaar, das vor dem Fork angelegt wird.

      Das hab ich mir auch schon überlegt, shared memory ist mMn nach einfachste. Trotzdem ist es irgendwie overkill.

      Ich versuche die LVA-Leitung zu erreichen. Bei den Programmierrichtlinien steht ja z.B., dass keine Signalbehandlung einzubauen ist mit Ausnahme eines Beispiels. Ich bin natürlich einer der Glücklichen die das erwischt haben. Vl haben sie bei kill() / killpg() die Ausnahme vergessen.

      --
      LG,
      Snafu
  3. Hallo!
    So das ganze hat sich nun geklärt.
    Das Verbot von kill() / killpg() bezog sich darauf, dass man beim normalen Programmablauf auf die Terminierung der Kindprozesse warten soll mittels wait() / waitpid().

    --
    LG,
    Snafu