Wie auf signal select() sofort zurückkehrt?

Habe ich einen worker-thread, der hört auf einem TCP-socket für eingehende Datenverkehr und die Pufferung der empfangenen Daten für den Haupt-thread zugreifen (nennen wir diese Buchse Eine). Aber der worker-thread hat auch zu tun einige regelmäßige Operationen (sagen wir, einmal pro Sekunde), auch wenn keine Daten ankommen. Daher verwende ich select() mit einem timeout, so dass ich nicht brauchen, zu halten polling. (Beachten Sie, dass der Aufruf receive() auf einem nicht blockierenden socket, und dann schlafen Sie für eine Sekunde ist nicht gut: die eingehenden Daten sollten sofort verfügbar sein für den Haupt-thread, auch wenn der Haupt-thread könnte nicht immer in der Lage sein, um es zu verarbeiten richtigen Weg, daher die Notwendigkeit der Pufferung.)

Nun, ich muss auch in der Lage sein, um ein signal worker-thread zu tun einige andere Sachen sofort; aus dem Haupt-thread, die ich brauche, um den worker-thread - select() Gegenzug sofort. Jetzt habe ich das folgendermaßen gelöst (Ansatz im wesentlichen übernommen aus hier und hier):

Bei Programm-Start der worker-thread erstellt zu diesem Zweck eine zusätzliche Steckdose des Datagramms (UDP) Typ aus, und bindet es zu einem zufälligen port (nennen wir diese Buchse B). Ebenso der main-thread erzeugt ein datagram-socket für das senden. In dem Aufruf select() wird der thread jetzt führt die beiden Eine und B in der fd_set. Wenn der Haupt-thread braucht, um zu signalisieren, es sendto()'s ein paar bytes an den entsprechenden port auf localhost. Zurück in der worker-thread, wenn B bleibt in der fd_set nach select() gibt, dann recvfrom() genannt wird und die empfangenen bytes werden einfach ignoriert.

Diese scheint sehr gut zu funktionieren, aber ich kann nicht sagen, wie ich die Lösung, vor allem, da es erfordert die Bindung eines zusätzlichen port für Bund auch, weil es fügt einige zusätzliche socket-API-Aufrufe, die fehlschlagen, Schätze ich, und ich habe nicht wirklich Lust, herauszufinden, die entsprechende Aktion für jeden der Fälle.

Ich denke, im Idealfall würde ich gerne eine Funktion, die Eine als Eingabe, und tut nichts, außer macht select() Gegenzug sofort. Allerdings weiß ich nicht so eine Funktion. (Ich denke, ich könnte zum Beispiel shutdown() die Buchse, aber die Nebenwirkungen sind nicht wirklich akzeptabel 🙂

Ist dies nicht möglich, ist die zweitbeste option wäre die Schaffung eines B das ist viel dummier als einer realen UDP-socket, und nicht wirklich erfordern die Zuteilung von beschränkten Ressourcen (über einen angemessenen Betrag von Speicher). Ich denke, Unix-domain-sockets würde genau das tun, aber: die Lösung sollte nicht viel weniger sein, cross-Plattform, als das, was ich derzeit habe, obwohl einige mäßige Menge von #ifdef Zeug ist gut. (Ich bin targeting hauptsächlich für Windows und Linux – und das schreiben von C++ übrigens.)

Bitte nicht schlagen refactoring, um loszuwerden, die zwei separate threads. Dieses design ist notwendig, da der Haupt-thread kann blockiert werden, für längere Zeiträume (z.B., wenn Sie einige intensive Rechen – und ich kann nicht starten regelmäßig aufrufen receive() aus der innersten Schleife der Berechnung), und in der Zwischenzeit muss jemand buffer für die eingehenden Daten (und aus Gründen, über was ich kontrollieren kann, es kann nicht der Absender).

Jetzt, wo ich dies Schreibe, erkannte ich, dass jemand definitiv beantworten Sie einfach "Boost.Asio", so hatte ich gerade meinen ersten Blick auf Sie... Konnte nicht finden, dass eine offensichtliche Lösung, aber. Beachten Sie bitte, daß ich auch nicht (leicht) beeinflussen, wie socket Eine ist erstellt, aber ich sollte in der Lage sein zu lassen, andere Gegenstände wickeln Sie es, wenn nötig.

InformationsquelleAutor der Frage Reunanen | 2008-12-21

Schreibe einen Kommentar