Nach dem Öffnen einer Pipe zu einem Prozess mit popen
gibt es eine Möglichkeit, den Prozess zu beenden, der gestartet wurde? (Mit ist nicht was ich will, denn das wird warten auf den Prozess zu beenden, aber ich muss es töten.)einen Prozess beenden, der mit popen gestartet wurde
Antwort
Verwenden Sie nicht popen(), und schreiben Sie Ihren eigenen Wrapper, der das tut, was Sie möchten.
Es ist relativ einfach zu fork(), und ersetzen Sie dann stdin & stdout mit dup2(), und rufen Sie dann exec() auf Ihr Kind.
Auf diese Weise haben Ihre Eltern die genaue Kind-PID und Sie können kill() verwenden.
Google Suche nach "popen2() Implementierung" für einige Beispielcode auf wie zu implementieren, was popen() tut. Es ist nur ein Dutzend oder so Linien lang. Entnommen dzone.com können wir ein Beispiel sehen, die wie folgt aussieht:
#define READ 0
#define WRITE 1
pid_t
popen2(const char *command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execl("/bin/sh", "sh", "-c", command, NULL);
perror("execl");
exit(1);
}
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
NB: Scheint, wie popen2() ist das, was Sie wollen, aber meine Verteilung scheint nicht mit dieser Methode zu kommen. Eigentlich
Der offensichtliche Weg ist System ("pkill process_name");
Dies ist eindeutig problematisch, wenn mehr als eine Instanz des Prozesses ausgeführt wird.
Dies ist der Fall, wenn mehrere Instanzen ausgeführt werden und eine präzise Instanz ausgewählt werden muss. – jldupont
popen startet eigentlich keinen Thread, sondern verzweigt einen Prozess. Wenn ich mir die Definition ansehe, sieht es nicht so aus, als gäbe es einen einfachen Weg, die PID dieses Prozesses zu bekommen und sie zu töten. Es könnte schwierig sein, den Prozessbaum zu untersuchen, aber ich denke, dass Sie besser mit den Funktionen pipe, fork und exec arbeiten sollten, um das Verhalten von popen nachzuahmen. Dann können Sie PID verwenden, das Sie von fork() erhalten, um den Kindprozess zu beenden.
, wenn der Prozess tut I/O (was es sein sollte, warum sonst popen
statt system
(3)?), Dann sollte pclose
Whack es mit einem SIGPIPE
das nächste Mal versucht, zu lesen oder zu schreiben, und es sollte schön überstürzen :-)
Ich habe etwas ähnliches in Python, wo Sie einen Unterprozess und alle Unterprozesse für diese gegabelt töten könnte. Es ist ähnlich wie die Lösung von Slacy. http://www.pixelbeat.org/libs/subProcess.py
Hier ist eine verbesserte Version von popen2 (Kredit ist fällig für Sergey L.). Die von Slacy veröffentlichte Version gibt nicht die PID des in popen2 erstellten Prozesses zurück, sondern die PID, die sh
zugewiesen ist.
pid_t popen2(const char **command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execvp(*command, command);
perror("execvp");
exit(1);
}
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
Die neue Version ist, ich habe Idee @slacy folgen mit
char *command[] = {"program", "arg1", "arg2", ..., NULL};
Ich sah keinen Unterschied in pid Teil; Kannst du Kommentare zum Unterschied Teil aktualisieren. – nayab
Danke Schach für deine Version, wirklich gut! –
genannt werden, die Funktion popen2 erstellen.
Aber Problem gefunden, wenn Child-Prozess stirbt, Elternprozess, der noch lesen Dateideskriptor outfp
nicht von der Funktion zurückkehren.
Das könnte durch Hinzufügen schließen unuse pipe auf Elternprozess beheben.
close(p_stdin[READ]);
close(p_stdout[WRITE]);
Wir können richtig pid neuen Prozess erhalten, indem bash als Shell verwenden.
execl("/bin/bash", "bash", "-c", command, NULL);
Wenn Kind-Prozess des Aufrufer Funktion popen2
soll Status des Kindprozesses durch Anruf sammeln pclose2
sterben. Wenn wir diesen Status nicht sammeln, kann der Prozess ein Zombie-Prozess sein, wenn er endet.
Dies ist der vollständige Code, der getestet und wie erwartet funktioniert.
#define READ 0
#define WRITE 1
pid_t
popen2(const char *command, int *infp, int *outfp)
{
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
else if (pid == 0)
{
dup2(p_stdin[READ], STDIN_FILENO);
dup2(p_stdout[WRITE], STDOUT_FILENO);
//close unuse descriptors on child process.
close(p_stdin[READ]);
close(p_stdin[WRITE]);
close(p_stdout[READ]);
close(p_stdout[WRITE]);
//can change to any exec* function family.
execl("/bin/bash", "bash", "-c", command, NULL);
perror("execl");
exit(1);
}
// close unused descriptors on parent process.
close(p_stdin[READ]);
close(p_stdout[WRITE]);
if (infp == NULL)
close(p_stdin[WRITE]);
else
*infp = p_stdin[WRITE];
if (outfp == NULL)
close(p_stdout[READ]);
else
*outfp = p_stdout[READ];
return pid;
}
int
pclose2(pid_t pid) {
int internal_stat;
waitpid(pid, &internal_stat, 0);
return WEXITSTATUS(internal_stat);
}
ich einfach in der (bash) Skript setzen, in der ersten Zeile:
echo PID $$
dann las ich die pid, und es verwenden, eine tun: kill (pid, 9)
popen ist käsig, um damit zu beginnen, das ist eine nette käsige Lösung des käsigen Problems. – stu
- 1. Wie schließe ich die Stdout-Pipe, wenn Sie einen Prozess beenden, der mit dem Python-Subprozess Popen gestartet wurde?
- 2. Wie kann ich einen Prozess mit VBScript beenden, der von einem bestimmten Benutzer gestartet wurde
- 3. Wie kann ich einen Java-Prozess beenden, der von ant exec plattformunabhängig gestartet wurde?
- 4. Python Popen: Wie kann ich den Subprozess beenden, der mit Popen erstellt wurde?
- 5. Ermitteln, ob der Prozess neu gestartet wurde
- 6. Wie kann ich einen Prozess in Erlang beenden, der nur den Modulnamen kennt, mit dem er gestartet wurde?
- 7. den Prozess zu beschränken, der von System.Diagnostics.Process gestartet wurde
- 8. einen Prozess in pythonw mit Popen Laufen ohne Konsole
- 9. Wie kann ich einen matrizenbasierten Job beenden, der von der Hive gestartet wurde?
- 10. Kill-Prozess gestartet mit System.Diagnostic.Process.Start ("FileName")
- 11. Wie Prozess beenden VBScript mit
- 12. So beenden Sie einen Prozess in VBScript
- 13. Beenden Sie einen Prozess nach Timeout mit VBScript
- 14. Wie kann man einen C# -Prozess beenden?
- 15. Wird erlang aufgezeichnet, wenn ein Prozess gestartet wurde?
- 16. C# -, wie Sie überprüfen, ob ein Prozess erfolgreich gestartet wurde
- 17. Kill einen Prozess und warten auf den Prozess zu beenden
- 18. Der richtige Weg, um einen Prozess in Java zu beenden
- 19. C# synchroner Prozess gestartet
- 20. Wie erkenne ich, wie mein Prozess gestartet wurde?
- 21. Wie kann man einen Prozess beenden, der neu startet? (Forever)
- 22. Sitzung wurde bereits gestartet
- 23. Popen bekommen pid von neu laufenden Prozess
- 24. Beenden Excel-Prozess
- 25. Problem mit popen
- 26. "StandardOut wurde nicht umgeleitet oder der Prozess wurde noch nicht gestartet" beim Lesen der Konsolenbefehlsausgabe in C#
- 27. warten Sie einen Prozess zu beenden und einen anderen Prozess ausführen
- 28. Wie kann ich Daten zu einem Prozess verschicken, der über Net :: SSH auf stdin gestartet wurde?
- 29. Wie kann ein ANT-Build-Skript einen Windows-Prozess beenden?
- 30. C# System.InvalidOperationException wurde ausgelöst: Prozess kann nicht gestartet werden, da kein Dateiname angegeben wurde
Dies löst nicht das Problem der Speicherduplizierung von fork. es ist möglich, dass wir aus diesem Grund keinen Anruf ausrufen wollen – Will
@phooji Was hat Python mit irgendetwas zu tun? –
@ MahmoudAl-Qudsi: Whoops. Ich muss mich über zu viele Python-Fragen gekümmert haben. [Früherer Python-bezogener Kommentar redigiert] – phooji