LINUX.ORG.RU

fwrite + много pread

 ,


0

1

Приветствую.

В продолжении темы

Напомню - пишу по кольцу с камеры на флешку без файловой системы через буфер fwrite кусками по 256КБ, из за нехватки времени заняться вопросом скачивание архива выполнялось в полурукопашном режиме через открытие отдельного FILE* или дескриптора в отдельном потоке и долгая перекачка по ентернетам.

Пришло время заняться вопросом отдать архив нескольким клиентам одновременно и собсна вопрос - можно ли через уже открытый FILE* и int fd = fileno(FILE*), используя pread со своим смещением в каждом потоке безопасно выполнять выгрузку одного и того же «файла»? или лучше для каждой выгрузки-потока выполнять свой open?

ЗЫ. на старте не знаю сколько будет одновременно читающих потоков.

★★★

Никаких проблем pread не создаст хоть в 1 поток хоть в 10. Осталось сделать наконец ещё один шаг - выкинуть ненужное stdio, файл открывать через open() и писать через write(), буфер записи реализовать самостоятельно.

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

спасибо, через фврайт пишется нормально без реализации самостоятельного захода солнца )

посмотрел уже strace [pid ] write(7, "..."..., 262144) = 262144

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

а при pread разве не так же будут в память подниматься данные? все таки в этот раз нужно последовательное чтение всех байт, а не как прошлый раз только условных 20

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

а при pread разве не так же будут в память подниматься данные? все таки в этот раз нужно последовательное чтение всех байт, а не как прошлый раз только условных 20

в клиентских pread ты-же эти данные куда-то читаешь и копируешь? лишний буфер, лишнее копирование. Клиенты которые только читают могут mmap`ить фрагменты и эффективно разделят общую память.

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

присваиваю адрес считанных байтов структуре ффмпега AVPacket и вызываю av_write_frame, потом делаю смещение на величину кадра и так весь буфер, т.е. сам я ничего никуда не копирую

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

присваиваю адрес считанных байтов структуре ффмпега AVPacket и вызываю av_write_frame, потом делаю смещение на величину кадра и так весь буфер, т.е. сам я ничего никуда не копирую

facepalm :-(

а pread как по вашему, что делает ? копирует

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

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

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

Он имеет ввиду что pread копирует из кеша ОС в память твоей проги. А mmap и правда не копирует, а отображает кеш напрямую в твоё адресное пространство. Но это всё мелочи по сравнению с временем на собственно чтение с диска.

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

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

ещё имел в виду, что когда несколько клиентов-ридеров работают с одним файлом и примерно в одной области, то mmap`ят они одну и ту-же память и не надо создавать (аллоцировать) чего-то дополнительного.

Не без проблем будет: с выравниванием по страницам придётся потрахаться, желательно чтобы и на носители тоже всё ровненько лежало.

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

Большое спасибо за ликбез, но наверное все таки на приад останавлюсь пока, поскольку не потребуется ммап анммап делать когда появляются читатели или держать его все время, ещё нет статистики но наверное больше одного читателя будет редко.

Нет пока времени на велосипедостроение и в том числе поэтому фврайт.

wolverin ★★★
() автор топика
Последнее исправление: wolverin (всего исправлений: 2)

А ещё можно использовать sendfile — копировать из файла в сокет мимо юзерспейса, с буферизацией только в ядерный page cache. Без отдельного open на каждое соединение не обойтись. Но это кмк не проблема.

iliyap ★★★★★
()