2011-01-04 3 views
3

Es gibt eine Möglichkeit, die Cwrite() serialisieren, so dass ich Bytes auf einem Socket schreiben kann, geteilt zwischen k-Threads, ohne Datenverlust? Ich stelle mir vor, dass eine Lösung für dieses Problem die Sperrung von Benutzerbereichen einschließt, und was ist mit Skalierbarkeit? Vielen Dank im Voraus.Die posix C write() und Thread-Sicherheit

Antwort

0

Da POSIX keine atomaren Garantien für send (2) angibt, müssen Sie wahrscheinlich einen Mutex verwenden. Bei dieser Art der Serialisierung geht natürlich die Skalierbarkeit verloren.

0

Ein möglicher Ansatz wäre die Verwendung des Verriegelungsmechanismus. Jeder Thread sollte auf eine Sperre warten, bevor er etwas in den Socket schreibt, und sollte das Schloss freigeben, sobald es fertig ist. Wenn alle Ihre Threads genau die gleiche Art von Nachrichten senden, hat das Empfängerende kein Problem beim Lesen der Daten, aber wenn verschiedene Threads unterschiedliche Arten von Daten mit möglichen anderen Informationen senden können, sollten Sie eine eindeutige Nachrichten-ID haben mit jeder Art von Daten verbunden und es ist besser, die Thread-ID auch zu senden (obwohl nicht notwendig, aber könnte Ihnen helfen, kleine Probleme zu debuggen).

Sie können eine Struktur wie haben:

typedef struct my_socket_data_st 
{ 
int msg_id; 
#ifdef __debug_build__ 
    int thread_id; 
#endif 
size_t data_size_in_bytes; 
.... Followed by your data .... 
} my_socket_data_t 

Skalierbarkeit auf eine Menge Dinge, einschließlich der Hardware-Ressourcen, hängt von der Anwendung ausgeführt werden würde. Da es sich um eine Netzwerkanwendung handelt, müssen Sie auch über die Netzwerkbandbreite nachdenken. Obwohl es keine gibt (es gibt ein paar, aber ich denke, Sie können sie für Ihre Anwendung für jetzt ignorieren) Beschränkung von OS beim Senden/Empfangen von Daten über einen Socket, aber Sie müssen darüber nachdenken, die send basierend auf synchronen oder asynchronen Ihre Anforderung. Auch da Sie ein Schloss nehmen, müssen Sie auch über Blockierung der Schleusen denken. Wenn die Sperre für andere Threads nicht leicht verfügbar ist, wird die Leistung um einen großen Faktor beeinträchtigt.

4

Ich denke, die richtige Antwort hängt davon ab, ob Ihre Threads synchron auf eine Antwort warten müssen oder nicht. Wenn sie nur eine Nachricht an einen Socket schreiben müssen und nicht darauf warten, dass der Peer antwortet, denke ich, dass die beste Antwort darin besteht, einen einzigen Thread zu haben, der Nachrichten aus einer Warteschlange schreibt, auf die die anderen Threads Nachrichten schreiben. Auf diese Weise können die Worker-Threads ihre Nachrichten einfach in die Warteschlange stellen und mit etwas anderem weitermachen.

Natürlich muss die Warteschlange durch einen Mutex geschützt werden, aber ein einzelner Thread muss nur die Sperre halten, solange er die Warteschlange manipuliert (garantiert ziemlich kurze Zeit). Die offensichtlichere Alternative, jeden Thread direkt in den Socket schreiben zu lassen, erfordert, dass jeder Thread die Sperre so lange hält, wie der Schreibvorgang abgeschlossen ist. Dies ist immer viel länger als nur das Hinzufügen eines Elements zu einer Warteschlange, da es sich bei dem Schreibvorgang um einen Systemaufruf handelt, der potenziell für eine lange Zeit blockiert werden könnte.

Auch wenn Ihre Threads eine Antwort auf ihre Nachrichten benötigen, kann es sich trotzdem lohnen etwas ähnliches zu tun. Ihr Socket-Wartungs-Thread wird komplexer, weil Sie auf dem Socket für Lese- und Schreibvorgänge etwas wie select() tun müssen, um die Blockierung zu verhindern. Außerdem müssen Sie Nachrichten mit Antworten abgleichen und die Threads informieren wenn ihre Antworten angekommen sind.