LINUX.ORG.RU

Где почитать HOWTO по реализации (circular/ring) буфера?

 ,


1

4

Нужно именно про буфер с несколькими «читателями»

Не могу нагуглить. Попадается все время только где читает один поток. А мне нужно чтобы читали несколько.

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

В лучшем случае я бы почитал про это где-нибудь в сети, но не могу нагуглить.

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

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

Т.е. постановка читателей в очередь? Бред получается, ибо в таком случае вообще буфер не нужен. Он же мне нужен для развязки читателя от писателя, а равно и для развязки читателей между собой.

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

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

deep-purple ★★★★★
() автор топика

Ну и пусть себе читают. Главное, синхронизироваться с писателями. Если нужна высокая скорость работы, то искать в сторону lock-free контейнеров.

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

А одинаковые читать нельзя?

Можно. Пусть второй накапливает у себя нужный объем и потом что-то делает.

В таком случае всеравно нужно внутри буфера смотреть за самым медленным.

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

Точнее, тебе нужно это: https://www.google.com/patents/US7716396

Как я понял из описания, ring buffer отдаёт данные один раз одному потоку, следующие потоки читают следующие ячейки. А вот circular buffer memory позволяет читать одно и то же с разной скоростью разным потокам.

kike
()
Ответ на: комментарий от deep-purple

Патент не может нагуглиться? Может.

Или не сойдёт за HOWTO? Там в патенте даже псевдокод на C-образном языке есть.

kike
()

подробно разЪжёвано у Кнута.

emulek
()
Ответ на: комментарий от deep-purple

Если ты переизобретёшь то, что описано в патенте, тебя это от дяди не спасёт.

kike
()
Ответ на: комментарий от deep-purple

Не, я к тому что «завтра» придет дядя и скажет: Ты чо мой запатентованный способ юзаешь, а?

Если ты не в US, можешь послать дядю в жопу.

hateyoufeel ★★★★★
()

Я такую штуку реализовывал для MJPEG-видео в реальном времени, чтобы все клиенты самые свежие кадры получали. Буфер на 4 кадра, в shm хранится номер последнего свежего. Т.к. время считывания готового кадра из буфера явно меньше времени накопления трех кадров, то проблем с битыми кадрами не было.

От задачи зависит: если у тебя очередь, которую должны полностью прочитать все клиенты, то придется вводить подобные ограничения; если же главное — прочесть свежие сообщения, то пофиг.

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

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

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

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

Но у тебя все читали одинаковые кусочки.

Нет, иначе хватило бы и двух кадров на буфер (типа двойной буферизации в OpenGL). Клиенты обращаются асинхронно и каждый со своей скоростью (пользователь выбирает частоту кадров в секунду). Т.е. пока демон пишет кадр4, клиент1 может читать кадр1, клиент2 — кадр3, а еще пара клиентов — считывать кадр2.

Думаю, если тщательно над твоей задачей покумекать, вполне можно придумать решение. Или изменить архитектуру задачи.

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

Что делать если клиенту А (сеть хорошая, бежит впереди) уже нужны следующие данные, а клиент Б (сеть медленная, плетется сзади) еще втупляет?

Слать в А последний кадр пока Б не просрется?

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

Чего пишешь-то? И неужто нельзя пропускать? Т.е. срем на клиента Б и обновляем содержимое буфера, а ему кидаем указатель на первый байт новых данных.

Ну или другой вариант: поток или процесс, обслуживающий клиента Б, делает копию содержимого буфера и говорит родителю, что все считано. Сам же продолжает этому тормозу данные допихивать. Если надо — еще порцию копирует из буфера, чтобы сервер не заставлял всех ждать, пока тормоз обработает. Сделать ограничение на итоговый размер буфера, скажем, в мегабайт. Если уже мегабайт сожрал, а клиент Б все тупит, обрываем соединение и опустошаем нафиг буфер. Хороший вариант.

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

Чего пишешь-то?

Ну, велосипед конечно же ))

И неужто нельзя пропускать?

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

Вобщем да, получаются варианты: а) ждать всем пока тормоз проснется; б) повторять из буфера всем успевшим last available data пока тормоз не проснулся; в) писать новые данные наплевав на тормоза, ой, на всех тормозов в очереди, ибо ориентир смещается на самого быстрого.

Может быть эти варианты поведения вынести в конфиг?

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

Проще одну реализацию сделать, но оставить концы для возможности дополнительных реализаций. А то замучишься же на все случаи жизни делать.

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