- Können wir send von einem Thread und recv von einem anderen auf demselben Socket aufrufen?
- Können wir mehrere Sends parallel von verschiedenen Threads am selben Socket aufrufen?
Ich weiß, dass ein gutes Design dies vermeiden sollte, aber mir ist nicht klar, wie sich diese System-APIs verhalten werden. Ich kann auch dafür keine gute Dokumentation finden.
Hinweise in die Richtung sind hilfreich.
c
networking
sockets
Jay
quelle
quelle
Antworten:
POSIX definiert send / recv als atomare Operationen. Wenn Sie also von POSIX send / recv sprechen, können Sie sie gleichzeitig von mehreren Threads aus aufrufen, und die Dinge funktionieren.
Dies bedeutet nicht unbedingt, dass sie parallel ausgeführt werden. Bei mehreren Sends wird der zweite wahrscheinlich blockiert, bis der erste abgeschlossen ist. Sie werden wahrscheinlich nicht so viel bemerken, da ein Sendevorgang abgeschlossen ist, sobald seine Daten in den Socket-Puffer gestellt wurden.
Wenn Sie SOCK_STREAM-Sockets verwenden, ist es weniger wahrscheinlich, dass Sie versuchen, Dinge parallel auszuführen, da send / recv möglicherweise nur einen Teil einer Nachricht sendet oder empfängt, was bedeutet, dass die Dinge aufgeteilt werden können.
Das Blockieren von send / recv auf SOCK_STREAM-Sockets wird nur blockiert, bis sie mindestens 1 Byte senden oder empfangen, sodass der Unterschied zwischen blockierend und nicht blockierend nicht sinnvoll ist.
quelle
send
kehrt zurück, sobald die Daten in den Sendepuffer gestellt wurden, und die Daten werden asynchron über den Netzwerkstapel an das Netzwerk weitergeleitet. Wenn Sie also einen Thread senden und einen Thread empfangen, ist es durchaus möglich (sogar wahrscheinlich), dass der sendende Thread viele Pakete sendet, bevor der empfangende Thread das erste Paket empfängt. Es ist völlig asynchron und nicht gleichzeitig.Der Socket-Deskriptor gehört zum Prozess, nicht zu einem bestimmten Thread. Daher ist es möglich, in verschiedenen Threads an denselben Socket zu senden / von diesem zu empfangen. Das Betriebssystem übernimmt die Synchronisation.
Wenn jedoch die Reihenfolge des Sendens / Empfangens semantisch bedeutsam ist, müssen Sie selbst (bzw. Ihr Code) eine ordnungsgemäße Reihenfolge zwischen den Vorgängen in den verschiedenen Threads sicherstellen - wie dies bei Threads immer der Fall ist.
quelle
Ich sehe nicht ein, wie paralleles Empfangen möglicherweise etwas bewirken könnte. Wenn Sie eine 3-Byte-Nachricht haben, könnte 1 Thread die ersten 2 Bytes und ein anderer das letzte Byte erhalten, aber Sie hätten keine Möglichkeit zu sagen, welches welches war. Wenn Ihre Nachrichten nicht nur ein Byte lang sind, können Sie auf keinen Fall zuverlässig dafür sorgen, dass mehrere Threads empfangen.
Mehrere Sends können funktionieren , wenn Sie die gesamte Nachricht in einem einzigen Anruf gesendet haben, aber ich bin mir nicht sicher. Es ist möglich, dass einer den anderen überschreibt. Dies würde sicherlich keinen Leistungsvorteil bringen.
Wenn mehrere Threads gesendet werden müssen, sollten Sie eine synchronisierte Nachrichtenwarteschlange implementieren. Lassen Sie einen Thread das eigentliche Senden durchführen, das Nachrichten aus der Warteschlange liest, und lassen Sie die anderen Threads ganze Nachrichten in die Warteschlange stellen. Dasselbe würde für den Empfang funktionieren, aber der Empfangsthread müsste das Format der Nachrichten kennen, damit er sie ordnungsgemäß deserialisieren kann.
quelle