0

Я пытаюсь написать серверную программу, которая поддерживает один клиент, до сих пор и в течение нескольких дней, когда я пытался его разработать, я пришел к выводу, что мне нужны потоки. Причина такого решения заключалась в том, что я беру данные из сокета wifi, а затем обрабатываю его и, наконец, записываю в файл, время обработки медленное и, следовательно, мне нужен входной поток -> круговой буфер -> выходной шаблон потока с потребителем-производителем модель, которая довольно распространена в сетевом программировании.Многопоточный проект программирования сокетов Linux

Теперь ситуация осложняется, так как мне нужно управлять отключением клиента и повторным подключением. Я думал использовать pthread_exit() и очищать все семафоры, а затем инициализировать их каждый раз, когда один клиент повторно подключается.

Мой вопрос в том, что это эффективный подход, то есть каждый раз, убивая потоки и семафоры и создавая их. Есть ли лучшие решения.

Спасибо.

ответ

-1

Некоторые комментарии и предложения.

1-В TCP, обнаруживая, что другая сторона отключила его, очень сложно, если не невозможно. Клиент может отключить отправку RST-сообщения TCP на сервер или отправку сообщения FIN, это хороший случай. Иногда клиент может отключиться без уведомления (сбой, отключение кабеля и т. Д.).

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

  • Кроме того, в зависимости от языка программирования и операционной системы вам может потребоваться сигнал с нарушенной трубкой (SIGPIPE) (в Linux, с C/C++), для сервера, пытающегося отправить сообщение через соединение, закрытое клиент.

2-Что касается семафоров, вы не должны чистить семафоры в любом особенных, когда клиенте разъединитель. При применении общих хороших методов блокировки и разблокировки мьютексов должно быть достаточно. Кроме того, с такими ресурсами, как дескрипторы файлов, вам необходимо освободить их до окончания потока либо путем возврата из функции запуска потока, либо с помощью pthread_exit. Возможно, я не понял эту часть вопроса.

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

  • Threads являются ресурсоемкими, и вы можете исчерпать ресурсы операционной системы, если вам нужно создать 1000 потоков, например.

  • Другая альтернатива - иметь только один потребительский поток, который управляет всеми соединениями (сокетами) асинхронно: a) Каждое соединение имеет свое собственное состояние. b) Основной поток проходит через все соединения и использует функцию «select» для обнаружения, когда соединение считывается или записи готовы. 3) Использование неблокирующих сокетов, но это не существенно, потому что из выбора вы знаете, какие сокеты готовы и не будут блокироваться.

  • Вы можете использовать функции select, poll, epoll.

Одна ссылка о некоторых и не блокирующих сокетов: Using select() for non-blocking sockets Другие ссылки с примером: http://linux.die.net/man/2/select

+0

Как отредактировано Я использую простые флаги, чтобы сигнальные потоки останавливались и в конечном итоге соединялись. Он хорошо работает для двух соединений, третье связано с проблемами. Должен ли я задерживать при закрытии предыдущего сокета и нового сокета. – Haswell

+0

Я закрываю все дескрипторы, прежде чем создавать новые сокеты fd для нового подключения. – Haswell

+0

Разве вы не используете стандартные функции сокетов, такие как bind, listen, accept и т. Д.? Код, который вы вставили, не имеет большого смысла для меня. – rodolk

0

Мой вопрос состоит в том, что является ли это эффективный подход, т.е. каждый раз, убивая нити и семафоры и повторно создавая их. Есть ли лучшие решения.

  1. Узнайте, как использовать не блокирующие сокеты и цикл событий. Или используйте библиотеку, которая предоставляет сеансы TCP для вас, используя неблокирующие сокеты под капотом. Например, boost::asio.
  2. Узнайте, как использовать многопоточность без загрязнения вашего кода с помощью любых примитивов синхронизации, используя передачу сообщений для обмена данными между потоками, а не общим состоянием. Библиотека циклов событий, которую вы используете для неблокирующего ввода-вывода, должна также обеспечивать средства для передачи сообщений с помощью сквозных потоков.
Смежные вопросы