Frage

Was passiert, wenn ich eine Steckdose haben, s, da noch keine Daten über sie vorhanden ist, ist es eine blockierende Buchse ist, und ich rufe recv auf sie aus zwei Threads auf einmal? Wird einer der Threads die Daten? Werden beide es bekommen? Wird der zweite Anruf Rückkehr mit einem Fehler recv?

War es hilfreich?

Lösung

Ein Thread wird es, und es gibt keine Möglichkeit, die erzählen.

Dies scheint nicht wie ein vernünftiges Design. Gibt es einen Grund, warum Sie zwei Threads müssen Aufruf recv() auf derselben Buchse?

Andere Tipps

Socket-Implementierungen sollten Thread-sicher sein, so genau ein Thread soll die Daten erhalten, wenn es verfügbar wird. Der andere Aufruf sollte nur blockieren.

Ich kann nicht eine Referenz für diese finden, aber hier ist mein Verständnis:

Eine Garantie des Herstellers von Thread-Sicherheit bedeutet nur, dass mehrere Threads kann jeder sicher ihre eigene Sockets verwenden; es garantiert nicht, Unteilbarkeit über einen einzigen Anruf, und es verspricht keine besondere Zuordnung der Daten der Buchse unter mehreren Threads.

Angenommen Thread A ruft recv () auf einem Sockel, der mit einer hohen Rate in Streaming-Daten des TCP empfängt. Wenn recv () muss ein Atom Anruf sein, fädeln dann A könnten alle anderen Threads von der Ausführung blockieren, weil sie kontinuierlich in allen Daten zu ziehen, laufen werden muss (bis zu seinem Puffer voll ist, sowieso.) Das wäre nicht gut. Daher würde ich nicht, dass recv annehmen () ist immun gegen Kontextwechsel.

Im Gegensatz dazu macht suppose Thread A einen Blockierung Aufruf recv () auf einem TCP-Socket und die Daten in langsam kommen. Daher der Aufruf recv () gibt mit errno Satz EAGAIN.

In jedem dieser Fälle, suppose Thread B ruft recv () auf der gleichen Buchse während Thread A noch Daten empfängt. Wenn nicht Thread eine Stoppdaten erhalten, um es übergeben, so dass Gewinde B Empfangen von Daten beginnen? Ich weiß nicht, von einer Unix-Implementierung, die diesen Thread A war in der Mitte einer Operation an der Steckdose zu erinnern versuchen; stattdessen ist es an der Anwendung (Threads A und B), um ihre Nutzung zu verhandeln.

Im Allgemeinen ist es am besten die App so zu gestalten, dass nur einer der Threads recv () aufrufen, auf einer einzigen Steckdose.

Von der Manpage auf recv rel="nofollow

  

Ein recv () auf einem Sockel SOCK_STREAM   gibt so viele Informationen verfügbar   als die Größe des Puffers zugeführten   halten.

Nehmen wir an, Sie TCP verwenden, da es nicht in der Frage angegeben wurde. So nehme an, Sie Thread A und Thread B beide Blockierung auf recv () für Socket s haben. Sobald s einige Daten hat empfangen werden ist eines der Themen entsperren wird, lässt A sagen, und die Daten zurück. Die zurückgegebenen Daten werden so weit von einigen zufälligen Größe sein, wie wir betroffen sind. Thread A prüft die empfangenen Daten und entscheidet, ob es eine vollständige „Nachricht“ hat, wo eine Nachricht ist ein Application Level-Konzept.

Thread A entscheidet es keine vollständige Nachricht hat, so ruft es recv () erneut. Aber in der Zwischenzeit B bereits auf dem gleichen Sockel blockiert, und hat den Rest der „Botschaft“ erhalten, die für Gewinde A. gedacht war ich lose hier bestimmt verwenden.

Nun sind beide Thread A und Thread B haben eine unvollständige Nachricht und wird, je nachdem, wie der Code geschrieben ist, die Daten weg als ungültig werfen, oder verursachen seltsame und subtile Fehler.

Ich wünsche, ich könnte sagen, ich wusste das nicht aus eigener Erfahrung.

Während also recv () selbst technisch Thread-sicher ist, ist es eine schlechte Idee, zwei Threads es gleichzeitig telefonieren zu haben, wenn Sie es für TCP verwenden.

Soweit ich weiß, es ist völlig sicher, wenn Sie UDP verwenden.

Ich hoffe, das hilft.

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