Frage

So ist die Situation dies. Ich habe eine C ++ Bibliothek bekam, die einige übergreifende Kommunikation tut, mit einer wait() Funktion blockiert und wartet auf eine eingehende Nachricht. Die Schwierigkeit besteht darin, dass ich ein timed Wartezeit, die mit einem Statuswert zurück, wenn keine Meldung in einer bestimmten Zeitspanne empfangen wird.

Die eleganteste Lösung ist wahrscheinlich die Bibliothek neu zu schreiben, ein zeitlich wartet auf seine API hinzuzufügen, aber für die Zwecke dieser Frage werde ich annehmen, dass es nicht machbar ist. (In Wirklichkeit sieht es schwierig, so möchte ich wissen, was die andere Option.)

Hier ist, wie ich dies mit einem langen Warteschleife tun würde, in Pseudo-Code:

while(message == false && current_time - start_time < timeout)
{
  if (Listener.new_message()) then message = true;
}

Ich will nicht einen vollen Warte dass eats Prozessorzyklen, though. Und ich will auch nicht nur auf einen sleep() Anruf in der Schleife zu vermeiden Last Prozessor hinzuzufügen, als dass Mittel langsame Reaktion. Ich möchte etwas, das dies mit einer richtigen Art von Blöcken und Unterbrechungen der Fall ist. Wenn die bessere Lösung beinhaltet das Einfädeln (was wahrscheinlich ist), sind wir bereits mit boost::thread, so dass ich es vorziehen würde, dass zu verwenden.

Ich bin Entsendung diese Frage, weil diese wie die Art von Situation scheint, dass ein klaren „best practices“ richtige Antwort haben würde, da es ein ziemlich übliches Muster ist. Was ist der richtige Weg, es zu tun?

Bearbeiten hinzuzufügen: Ein großer Teil meiner Sorge ist, dass diese an einer Stelle in dem Programm, das sowohl leistungskritische und kritische ist zu vermeiden Race Conditions oder Speicherleck. Während also „Verwendung von zwei Threads und ein Timer“ hilfreiche Ratschläge sind, ich versuche immer noch links, um herauszufinden, wie man tatsächlich auf diese Weise in einer sicheren und korrekten Umsetzung, und ich kann ich leicht sehen, machst Anfängerfehler in dem Code, dass ich weiß nicht einmal, die ich gemacht habe. Somit würde einige tatsächliche Beispiel-Code wirklich geschätzt!

Auch habe ich eine Sorge um die mehrere Threads Lösung: Wenn ich die „um die Blockierung Anruf in einem zweiten Thread setzt und machen Sie eine timed-Warte auf diesem Thread“ verwende Verfahren, was zu diesem zweiten Thread passiert, wenn die blockiert rufen Sie nie zurückkehrt? Ich weiß, dass die timed-Wartezeit in dem ersten Thread zurückkehren und ich werde sehen, dass keine Antwort geschehen ist und weiter mit Dingen, aber habe ich dann „durchgesickert“ einen Thread, der für immer in einem blockierten Zustand sitzen wird? Gibt es eine Möglichkeit, das zu vermeiden? (Gibt es eine Möglichkeit zu verhindern, dass sie und vermeiden Sie den zweiten Thread Speicher undicht?) Eine Komplettlösung zu dem, was ich brauchen würde brauche Lecks zu vermeiden, wenn der Sperr Anruf nicht zurückkehrt.

War es hilfreich?

Lösung

Sie könnten sigaction(2) und alarm(2) verwenden, die sowohl POSIX sind. Sie legen eine Rückrufaktion für die Timeout sigaction verwenden, dann stellen Sie einen Timer-Alarm verwenden, dann blockiert Anruf. Der Sperr Anruf unterbrochen wird, wenn sie nicht vollständig in der gewählten Timeout bedeutet (in Sekunden, wenn Sie feinere Granularität müssen Sie setitimer(2) verwenden können).

Beachten Sie, dass Signale in C etwas behaart sind, und es gibt ziemlich beschwerlich Beschränkung auf das, was Sie in Ihrem Signal-Handler tun können.

Diese Seite ist nützlich und ziemlich prägnant: http://www.gnu.org/s/libc /manual/html_node/Setting-an-Alarm.html

Andere Tipps

Was Sie wollen, ist so etwas wie wählen (2) , auf die je OS Sie zielen.

Es klingt wie Sie einen ‚Monitor‘ benötigen, zum Signalisieren Verfügbarkeit von Ressourcen auf Threads über einen gemeinsamen Mutex (in der Regel). In Boost.Thread ein condition_variable könnte den Job.

Sie können unter timed Schlösser : Ihre Sperrung Methode kann die Sperre aquire, bevor es zu warten und loslassen, sobald die Daten verfügbaren ist. Sie können dann versuchen, das Schloss (mit einem Timeout) in Ihrer zeitlichen Warte Methode zu erwerben.

kapselt die Sperrung Anruf in einem separaten Thread. Haben einen Zwischennachrichtenpuffer in dem Thread, der durch eine Bedingungsvariable bewacht wird (das wie zuvor). Machen Sie Ihre Haupt-Thread timed-Warte unter dieser Bedingung variabel. Erhalten Sie die zwischengespeicherten Nachricht, wenn die Bedingung erfüllt ist.

setzt also im Grunde eine neue Schicht, die zeitlich-Wartezeit zwischen der API und Ihrer Anwendung. Adapter-Muster.

In Bezug auf

  

Was passiert mit diesem zweiten Thread, wenn der blockierten Anruf nie zurückkehrt?

Ich glaube, es ist nichts Sie tun können, erholen sauber ohne die Zusammenarbeit von der aufgerufenen Funktion (oder Bibliothek). ‚Sauber‘: alle Ressourcen, die von diesem Thread, einschließlich Speicher, andere Threads, Schlösser, Dateien, Sperren auf Dateien, Steckdosen, GPU-Ressourcen im Besitz Reinigung ... Un -cleanly, können Sie in der Tat töten die Ausreißer-Thread.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top