TCP Accept and Go-Parallelitätsmodell
Das Go-Parallelitätsmodell betont die Verwendung von Kanälen für die Kommunikation zwischen Goroutinen. Wenn jedoch mit TCP-Listenern in Go gearbeitet wird, blockiert die Methode net.TCPListener.Accept() die aktuelle Goroutine, bis eine Verbindung akzeptiert wird, was scheinbar im Widerspruch zum Parallelitätsparadigma von Go steht.
Fehlende richtige Auswahl und Blockierungsoptionen
Im Gegensatz zu Systemannahmeaufrufen fehlt Accept() die richtige Auswahlunterstützung und die Möglichkeit, Blockierungsoptionen für Server-Sockets festzulegen. Dies zwingt Entwickler dazu, auf die folgende Problemumgehung zurückzugreifen:
<code class="go">acceptChannel = make(chan *Connection) go func() { for { rw, err := listener.Accept() if err != nil { ... handle error ... close(acceptChannel) ... return } s.acceptChannel <- &Connection{tcpConn: rw, .... } } }()</code>
Dieses Muster ermöglicht das Multiplexen von Accept() mit anderen Kanälen mithilfe von select, führt jedoch eine separate Goroutine für jeden Socket ein, der abgehört wird.
Ist das die richtige Redewendung?
Dieser Ansatz ist tatsächlich gültig und folgt dem Go-Parallelitätsmodell. Goroutinen sind leichtgewichtig und kostengünstig, daher ist die Erstellung mehrerer Goroutinen für das Socket-Listening im Allgemeinen akzeptabel.
Alternativer Ansatz
Für anspruchsvollere Anforderungen, wie die Implementierung einer Auswahl mit einem Timeout , man kann neue Verbindungen zu einem Kanal pushen und ihn mit einem Timer multiplexen:
<code class="go">newConns := make(chan net.Conn) // For every listener spawn the following routine go func(l net.Listener) { for { c, err := l.Accept() if err != nil { // handle error newConns <- nil return } newConns <- c } }(listener) for { select { case c := <-newConns: // new connection or nil if acceptor is down case <-time.After(time.Minute): // timeout branch } }</code>
Dieser Ansatz ermöglicht eine bessere Kontrolle über das Auswahl- und Timeout-Verhalten.
Zusammenfassend lässt sich sagen, dass beim Akzeptieren ()-Methode blockiert, passt sie immer noch in das Go-Parallelitätsmodell. Die Wahl des Ansatzes hängt von den spezifischen Anforderungen und Leistungsüberlegungen der Anwendung ab.
Das obige ist der detaillierte Inhalt vonUmgang mit TCP-Akzeptanzen in Go-Parallelität: Ist die Verwendung einer dedizierten Goroutine der beste Ansatz?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!