LINUX.ORG.RU

Блокируемый ввод/вывод в многопоточном сервере


0

1

Доброго времени суток!
Представим, что у нас есть многопоточный сервер с блокируемым read(), который обрабатывает данные из TCP-соединений. Данные идут с промежутками, так что потоки периодически просто ждут данные из read().
Если для потока данных нет, то будет ли ОС переключаться на этот поток и какой-то промежуток времени ждать данные, или при отсутствии данных она даже не переключится на заблокированный поток?

неправильно думаеш
при поступлении данных с сетевой - они на этом же процессоре - пошлються в буффер сокета -и на этом же процессоре пробудят нужный процесс который и заберет данные

если проц будет занят - то данные получаться по шедуллеру

ae1234 ★★
()

Поток на блокирующем read будет спать до тех пор, пока не появятся данные, или вызов не будет прерван сигналом (получим EINVAL)

yoghurt ★★★★★
()

переключаться чтобы ждать? ЛОЛШТО?

redixin ★★★★
()

при preemptive multitasking ос переключается между всеми потоками и процессами постоянно, выделяя каждому время для работы. что делает поток ОС не волнует.
время, выделяемое ОС зависит от приоритета котока.

кури операционные системы.

anonymous
()
Ответ на: комментарий от anonymous

при preemptive multitasking ос переключается между всеми потоками и процессами постоянно

Если задача выполняет блокирующее I/O, ждёт сигнала или делает sleep, то переключения на такую задачу не делается (пока данные не будут получены, сигнал не поступит, или время sleep не истечёт), а timeslice не расходуется.

quasimoto ★★★★
()

Тред полон наркоманов. Во-первых, не стоит уповать на то, как идут данные — с равными промежутками, хаотически или сплошным потоком. Во-вторых, делать многопоточный сервер таким способом (один поток — один сокет — один read()) — неправильно. man select, epoll, aio. В третьих, поток пробуждается из спячки по событиям, а не просто так. Одно из таки событий — приход данных в буфер сокета, на котором поток висит в read()'е.Система не дергает спящие потоки для того, чтобы они сами проверили, есть ли данные в сокете, т.к. это маразм.

anonymous
()
Ответ на: комментарий от anonymous

А можно ли в lInux на С делать подобие пула потоков? Например, для каждого принятого куска данных при мультиплексировании ввода/вывода создавать поток и передавать ему данные на обработку. Или накладные расходы на создания потоков будут большими? Какие вообще паттерны применимы для моей задачи?

ares4322
() автор топика
Ответ на: комментарий от ares4322

hint: никто не заставляет тебя создавать поток каждый раз, как появляются данные. Собственно, понятие «пул» это и подразумевает. О твоей задаче я не слова не услышал, только о мытарствах с потоками и read(), но, судя по твоим вопросам, могу только посоветовать делать все проще и не заморачиваться с потоками вообще.

anonymous
()
Ответ на: комментарий от yoghurt

Так а как тогда делать?
Задача такая: есть долгоживущие TCP-соединения и от них с разной периодичностью приходят данные (примерно раз в секунду), которые нужно разбирать и класть в БД.

ares4322
() автор топика
Ответ на: комментарий от ares4322

Диспатчить данные в потоки-воркеры для обработки. Поток выбирать исходя из загруженности его входящей очереди. В чём проблема-то?

yoghurt ★★★★★
()
Ответ на: комментарий от ares4322

раз в секунду

Нужна ли здесь многопоточность вообще? Пусть данные себе скапливаются в буферах сокетов, пока ты с БД возишься.

anonymous
()
Ответ на: комментарий от anonymous

Во-вторых, делать многопоточный сервер таким способом (один поток — один сокет — один read()) — неправильно. man select, epoll, aio

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

slackwarrior ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.