Безопасна ли резьба closesocket? - PullRequest
5 голосов
/ 25 марта 2012

Безопасно ли, если я хочу вызвать closesocket () для сокета сервера из 1 потока, который отделен от другого потока, который запускает сервер с использованием того же сокета сервера?

Ответы [ 2 ]

5 голосов
/ 25 марта 2012

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

Степень, в которой это опасно (и может ли это вообще произойти), во многом зависит от вашего кода. Это может не произойти, если вы никогда не создадите больше сокетов после закрытия сокета сервера. Но это все еще концептуально очень неправильно, и любой компетентный рецензент вашего кода посчитает это очень плохим.

Редактировать: Решением подобных проблем является защита дескриптора ресурса (а не самого ресурса) с помощью блокировки чтения-записи (rwlock). Доступ к дескриптору ресурса (целочисленная переменная, содержащая номер сокета, в вашем случае) требует удержания блокировки «чтения» на нем, независимо от того, будете ли вы выполнять ввод или вывод или другую операцию, используя ресурс, на который он ссылается. Для освобождения ресурса (и сохранения значения часового типа, например -1, в переменной, содержащей дескриптор), требуется блокировка записи.

1 голос
/ 25 марта 2012

Да, это не проблема. Естественно, будут исключения / ошибки, сгенерированные в других потоках, которые имеют невыполненные вызовы в сокете, но в самом сетевом стеке (который должен быть потокобезопасным из-за всех различных процессов / потоков, которые обычно его используют ), не будет поврежден.

...