Это сеть go.Close() идемпотентен?

#go

#Вперед

Вопрос:

В io.Closer документации интерфейса говорится:

Поведение Close после первого вызова не определено. Конкретные реализации могут документировать свое собственное поведение.

А как насчет net.Conn функции a Close() ? Могу ли я безопасно вызывать его более одного раза?

В частности, мне интересно, смогу ли я defer c.Close() в случае, если я вернусь раньше из-за ошибки, но все же явно вызываю c.Close() , а не заставляю клиента ждать, пока я закончу фоновую обработку.

Ответ №1:

Ну, net.Conn это интерфейс, так что это зависит от конкретной реализации.

Я проверил реализацию в TCPConn UDPConn и IPConn структурах. Похоже, они содержат эту реализацию net.Conn интерфейса.

Эта реализация распространяет Close() вызов на свой базовый файловый дескриптор, что означает, что в системах Unix затем вызывается эта функция.

Мы должны пойти еще ниже, поскольку следующий вызов относится к мьютексу, который используется файловым дескриптором.

Если соединение предварительно закрыто и мьютекс освобожден, кажется, что оно возвращает false, а функция файлового дескриптора Close() возвращает ошибку netclosing error.

Итак, я могу сказать, что вы не должны вызывать его более одного раза, так как он вернет ошибку в случаях, подобных этому, который я описал. Но он также может не выдавать ошибки в других. Как говорится в документации — это неопределенное поведение.