LINUX.ORG.RU

Поясните один момент с race condition

 , ,


0

1

На сях будет! Не плюсы! Однако, в принципе примеры на плюсах приемлю, но ожидаю что они будут легко воспроизведены и на сях.

Есть два треда в приложении. Вернее еще даже нет, но будет. Сейчас пока теория.

Один тред пишет куда-то там значения. Второй читает.

Но тут будет нюанс. Читатель и писатель могут читать и писать с различной частотой (из конфига при запуске). Причем и тот и тот могут быть медленнее или быстрее друг друга в 4 или даже 8 раз.

Что я уже юзал — мьютексы. Они медленные. Вернее, если один будет обращаться чаще другого, то из-за неатомарности мьютексов, треды будут попеременно или как попало просирать свою законную очередь, а это критично.

Что я не юзал — семафоры. Но это, насколько я знаю частный случай мьютекста (ну или наоборот), лайтмьютексы вобщем. Это не так? Поясните плиз.

Что еще? Просто volatile будет ли достаточно?

Другие варианты?

volatile будет мало. У Майерса даже этот момент очень подробно расписан.

Семафор это не лайтмьютекс. Мьютекс со счётчиком, грубо говоря.

Попробуй ещё atomic.

Вполне возможно, что тебе нужно поведение, что читать нужно только тогда, когда поток записи что-то записал. Тогда кури в сторону condition_variable.

zamazan4ik ★★
()

Что я не юзал — семафоры. Но это, насколько я знаю частный случай мьютекста (ну или наоборот)

Именно что наоборот. Мютекс - одноместный семафор.

В твоём случае я бы сделал очередь, если других ограничений нет.

hateyoufeel ★★★★★
()

Если Вам подойдёт, то как уже сказали выше, может подойти и очередь. там уже обернёте в condition_variable работу с ней и всё. Для ознакомления почитайте про Concurent data structures (Максим Хижинский (или Хинжинский, не помню уже) вроде как, есть видео с конференций, слайды и цикл статей на хабре).

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

Можно и через фьютексы, только это не совсем кроссплатформа вроде как. Да и наверное ТСу здесь не фьютексы нужны.

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

Ну вот в семафоре вроде как ставится и размер очереди. А как она будет на большой частоте обращений работать? Не упрусь ли я в те же яйца что и с мьютексами?

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

читать нужно только тогда, когда поток записи что-то записал

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

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

тогда самым простым решением для вас будет atomic, если это просто переменная. Если какой-то обьект, то Вам придётся защищать мьютексом. Можете попробовать юзать posix фьютексы - они должны быть быстрее, но я не имел опыта работы с ними.

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

Нет, будет структура. Но тут что первое пришло в голову — вместо полей структуры использовать (или ссылать структуру на них) просто переменные, и вот сами переменные уже заатомить. Не прокатит?

Фьютексы пойду почитаю пока.

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

Да, это уже интереснее, тоже почитаю. Спасибо!

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

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

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

Это только в том случае если писатель пишет чаще чем читатель читает. Да и всеравно как-то придется сигналить что меняемся структурами.

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

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

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

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

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

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

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

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

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

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

Кольцевой буфер? Уверен точно будет толк если писатель пишет быстрее. А что если наоборот? Рассчитать рэтио и «рипитить» писателем в буфер данные для более быстрого читателя?

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

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

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

Для более быстрого читателя можно просто использовать другую структуру данных - ту же очередь, с возможностью поспать. Тут зависит ещё от того, каким образом задаётся «скорость».

наблюдал разреженные данные у читателя, а при понижении частоты обращений все становилось нормально

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

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

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

с возможностью поспать

Согласен. Нечего просто так дрочить буфер повторяющимися значениями.

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

Если писатель быстрее, то пусть спит промежутками равными скорости читателя, и пусть пишет сразу разреженно, т.к. тут в любом случае аппроксимация (децимация) уже происходит так и так. Разруливать мьютексами.

Тогда буфер будет одной структуры на любой расклад.

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

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

то из-за неатомарности мьютексов

Ещё до появления atomic в C/C++ мьютексы были атомарны, ведь именно с их помощью можно было (да и по-прежнему можно) обращаться к защищённым ими переменным атомарно.

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

Я имел ввиду «неатомарность во времени», латентность, задержку.

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

spinlock, если запись длится очень короткое время.

invy ★★★★★
()

Вернее еще даже нет, но будет. Сейчас пока теория.

Что я уже юзал — мьютексы. Они медленные.

Так юзал и измерял в своём приложении или нет?

ilammy ★★★
()

Что еще? Просто volatile будет ли достаточно?

Да что ж вы все за этот volatile так хватаетесь?

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