Функция unix accept () дважды возвращает один и тот же файловый дескриптор

У меня проблема с моей программой многопоточного сетевого сервера.

У меня есть основной поток, который прослушивает новые клиентские подключения. Я использую Linux epoll для получения уведомлений о событиях ввода / вывода. Для каждого входящего события я создаю поток, который принимает () новое соединение и назначает ему fd. При большой нагрузке может случиться так, что один и тот же fd назначается дважды, что приводит к сбою моей программы.

Мой вопрос: как система может переназначить fd, который все еще используется другим потоком?

Спасибо,

1

Решение

Предположительно, здесь есть состояние гонки — но, не видя ваш код, его сложно диагностировать.

Вы бы лучше accept в главном потоке, а затем передайте принятый сокет новому потоку.

Если вы передадите сокет прослушивания в новый поток, чтобы затем выполнить принятие — вы попадете в состояние гонки.

Для получения дополнительной информации вы можете посмотреть здесь: https://stackoverflow.com/a/4687952/516138

А также этот хороший фон по эффективности сети (хотя, возможно, немного устарел).

3

Другие решения

Вы должны вызвать accept () в том же потоке, который вы вызываете epoll() на. В противном случае вы предлагаете условия гонки.

0

Файловые дескрипторы модифицируются «на основе процесса». Это означает, что они уникальны для каждого процесса. Это означает, что несколько потоков могут использовать одни и те же файловые дескрипторы в одном и том же процессе.

Имея accept Системный вызов, возвращающий один и тот же файловый дескриптор в одном и том же процессе, является очень убедительным свидетельством того, что некоторые ваши потоки закрывают предыдущую «версию» повторного файлового дескриптора.

Проблемы, подобные этой, могут быть сложными для отладки в сложных программах. Чтобы определить это в системе Linux, используйте strace команда. Можно бежать strace -f -e trace=close,accept4,accept,pipe,open <your program>, Это выведет на ваш экран соответствующие системные вызовы, указанные в команде, а также поток, вызывающий его.

0
По вопросам рекламы [email protected]