Ich mache eine Art Shell: Abhängig vom Benutzereintrag muss ich eine Funktion aufrufen. Ich kann den Inhalt dieser aufgerufenen Funktionen nicht ändern, da mein Programm nur ein Client ist und keine Sichtbarkeit hat.Wie man einen Funktionsaufruf "unterbricht"?
Aber ich möchte die Möglichkeit für den Benutzer, den Anruf mit CTRL+C
zu beenden. Hier ist der minimale Code:
#include <csignal>
#include <iostream>
#include <unistd.h>
void do_thing(void)
{
std::cout << "entering in do_thing()\n";
while(42)
::sleep(1);
}
extern "C" {
void signal_handler(int);
}
class Shell
{
friend void signal_handler(int);
public:
static Shell & Instance(void)
{
static Shell instance;
return instance;
}
int run(void)
{
std::string buff;
while ((std::cin >> buff))
{
if (buff == "foo")
do_thing(); // this must be terminable
else
std::cout << "(nothing)\n";
}
return 0;
}
private:
Shell(void)
{
::signal(SIGINT, signal_handler);
}
void signal(int sig)
{
if (sig == SIGINT)
;// must terminal the function call
}
};
extern "C" {
void signal_handler(int sig)
{
Shell::Instance().signal(sig);
}
}
int main(void)
{
return Shell::Instance().run();
}
I drei Möglichkeiten in Betracht gezogen:
- ich versuchte, eine Thread-Klasse von
std::thread
, mit einemkill()
Verfahren abgeleitet zu schaffen, die eine Ausnahme ausgelöst. Der Funktionsaufruf befindet sich in einem try-catch-Block. Es funktioniert, aber das ist eine schlechte Lösung, da der Destruktor nicht aufgerufen werden kann und die Ressource niemals freigegeben wird. - Ich überlegte,
fork
zu verwenden, aber ich denke, es ist ein Overkill, nur die Möglichkeit zu erhalten, einen Funktionsaufruf zu unterbrechen. - Ich habe versucht, eine Ausnahme von der Signal-Handler zu werfen, aber ich sah, dass dies eine schlechte Idee ist, da dies sehr Compiler/Betriebssystem abhängigen Code ist.
Wie können Sie das Ding machen? Was ist die bessere Lösung?
Hinweis: Ich löschte den alten Beitrag, weil es in der Nähe angefordert wurde, und berücksichtigt die C/C++ - Tags.
Habe ich diese Minuten nicht gelesen? –
Einer der Punkte von Ausnahmen und Stapelabwickeln ist, dass Objekte außerhalb des Bereichs liegen und normal zerstört werden.Nicht, dass es sowieso eine Rolle spielt, da die Ausnahme in Ihrem Thread und nicht im Kontext des Threads, der Ihren "Befehl" ausführt, geworfen wird. –
Es ist nicht möglich, einen Funktionsaufruf abzubrechen, noch ist es möglich, einen Thread zu beenden (Ihre 'kill()' Methode kann das unmöglich tun --- Sie scheinen eine ungewöhnliche Definition von "Arbeiten" zu haben und vielleicht eine Art Missverständnis von C++ - Ausnahmen). Der einzige (ja, der ** der ** der ** einzige **) Weg, einen Ausführungsablauf zu haben, der von außen abgebrochen werden kann, unabhängig davon, wofür ein separater Prozess erstellt werden soll. Also ja, 'fork()'. –