2016-12-22 2 views
0

Ich öffnete einen Prozess (GNUplot) von C++ mit der Funktion popen(). Wenn ich den Vorgang mit STRG + C beende, empfängt GNUplot auch das Signal SIGINT. Ich möchte verhindern, dass dies geschieht, da es sich ungünstig auf meine Arbeit auswirkt. (Ich bevorzuge es, das Signal mit meiner eigenen Signal-Handler-Funktion zu behandeln). Wie mache ich das?Wie verhindert man, dass ein mit popen() in C++ geöffneter Prozess ein SIGINT-Signal empfängt?

Ich plotten mit dem Befehl plot '-' und durchlaufen alle Werte, die ich plotten möchte. Wenn das Gnuplot SIGINT in der Mitte empfängt, hört es möglicherweise auf, in der Mitte zu zeichnen, ohne die gesamte Handlung zu vervollständigen. Ich möchte, dass es die gesamte Handlung vervollständigt. Das ist der ungünstige Effekt, den ich habe.

+0

Bitte erläutern Sie, welchen ungünstigen Effekt Sie vermeiden möchten. –

+0

Endlich habe ich Ihre Frage abgelehnt, weil Sie sie nicht bearbeitet haben, um zu erklären, welchen "ungünstigen Effekt" Sie vermeiden möchten. –

+0

@BasileStarynkevitch Ich habe die Frage –

Antwort

0

popen(3) läuft eine neue Shell /bin/sh -c in der Befehlszeichenfolge.

Die trap builtin der Shell behandelt Signale; mit einem leeren ersten Argument ignoriert es es. So könnten Sie tun

FILE* f = popen("trap '' TERM INT; gnuplot", "w"); 

BTW, POSIX trap die Signale erfordert ohne SIG Präfix benannt werden.

Aber das wird nicht funktionieren, da gnuplot selbst ist explizithandling signals. Es gibt keine Möglichkeit, dies außerhalb von gnuplot zu vermeiden. Aber nutzen Sie die free software Art von gnuplot: Laden Sie den Quellcode herunter, studieren Sie ihn und patchen Sie ihn für Ihre bizarren Bedürfnisse. FWIW, SIGINT und signal erscheinen an mehreren Stellen im Quellcode von gnuplot-5.0.5.

Sie sollten jedoch (statt mit popen) betrachten das niedrige Niveau System aufrufen ruft explizit (fork, execve, pipe, dup2, waitpid, signal ...). Lesen Sie Advanced Linux Programming für Details.


Ich vermute stark, dass Ihre Frage ein XY problem ist. Sie erklären nicht, welchen "ungünstigen Effekt" Sie eigentlich vermeiden möchten, und ich schätze, Sie könnten es sonst vermeiden.

Ich plotte mit dem Befehl plot '-' und iteriere durch alle Werte, die ich plotten möchte. Wenn das Gnuplot SIGINT in der Mitte empfängt, hört es möglicherweise auf, in der Mitte zu zeichnen, ohne die gesamte Handlung zu vervollständigen. Ich möchte, dass es die gesamte Handlung vervollständigt.

Eigentlich könnten Sie eingerichtet zwei oder drei Rohrleitungen (eine für Eingang, einen Ausgang für vielleicht eine für Stderr, wie auf gnuplot Seite gesehen) für gnuplot. Sie müssen die Low-Level-Systemaufrufe gehen (explizite Aufrufe an pipe(2), fork(2) usw. etc ...). Ihr Programm sollte dann einige event loop (wahrscheinlich basierend auf poll(2) ...) haben. Und Sie würden ein print "DONE"command gnuplot senden nach jedem plot '-' (nicht mit dem entsprechenden set print '-' oder haben ein anderes Rohr für den Stderr von gnuplot zu initialisieren vergessen). Ihre Ereignisschleife würde dann die DONE Nachricht zur Synchronisierung abfangen. Lesen Sie auch this.

+0

bearbeitet. Mein Vorschlag ist es, 'popen' zu vermeiden und die untergeordneten Systemaufrufe zu verwenden. –

+0

Ich habe einen Tippfehler gemacht, es ist 'Falle' 'TERM' nicht 'SIGTERM'; aber ich empfehle, 'popen' in deinem Fall zu vermeiden. –

+0

Dein Code funktioniert! –

0

Ich hatte ähnliches Problem wie Sie.Ich verwende den tc-Befehl mit dem Parameter -batch und ich muss ihn am Leben halten, bis er nach dem Erreichen des Limits beendet wird und geschlossen wird. Mein Problem war, dass ich zwei asynchrone Popen-Prozesse ausführte und nach dem Auslösen einer Ausnahme wurde der zweite Prozess beendet. Viele Speicherauszüge usw. Nachdem ich dieses Problem gefunden und behoben habe, kann ich nun mit SIGINT, SIGTERM, ctrl + c umgehen, ohne etwas darüber zu wissen. Keine Notwendigkeit für Fallen oder ähnliches.

Verwandte Themen