вопросы о многопоточности для сокетов / tcp-соединений - PullRequest
2 голосов
/ 21 марта 2010

У меня есть сервер, который подключается к нескольким клиентам, используя соединения TCP / IP, используя C в Unix. Поскольку он не будет иметь более 20 соединений одновременно, я решил использовать поток для каждого соединения / сокета. Но проблема заключается в записи в сокеты, так как я буду отправлять клиентские сообщения с запросами пользователей. Как только каждый сокет обрабатывается потоком, как мне взаимодействовать с созданным потоком для записи в сокеты? Должен ли каждый поток просто читать из сокетов, а я буду писать в сокеты в основной программе? Не уверен, что это хороший способ сделать это.

Ответы [ 3 ]

2 голосов
/ 21 марта 2010

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

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

Но как только вы это сделаете, вы столкнетесь со сложностью использования select () / poll () И многопоточности, что приводит к большим накладным расходам. Поэтому, если по какой-то причине вам абсолютно не нужна многопоточность, я согласен с предыдущими постерами - лучше всего обрабатывать все сокеты в одном потоке с помощью select () или poll ().

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

2 голосов
/ 21 марта 2010

Звучит так, как будто вам, вероятно, будет лучше с одним потоком и мультиплексированием сокетов (используя select, poll и т. Д.). Это позволит избежать условий гонки и требований блокировки, которые в противном случае усложнят написание программы.

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

Итак, я бы сказал, чтобы получить работающую реализацию, использующую один поток, ТОГДА, если при тестировании производительности вы обнаружите, что его не хватает, реорганизуйте его для использования многопоточности, если это кажется лучшим вариантом для решения проблем производительности (конечно вы будете его профилировать и т. д.).

1 голос
/ 21 марта 2010

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

Тем не менее, я бы протестировал производительность использования одного потока и выберите / опрос , прежде чем использовать многопоточный подход.

...