875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
1 | |
Синхронизация доступа к разделяемой памяти21.02.2017, 12:08. Показов 10183. Ответов 73
Метки нет (Все метки)
Когда потоки являются дочерними по отношению к процессу тут все просто - объект мьютекса находится в общей памяти и используя этот объект можно делать mutex.lock() определенной секции а при завершении работы mutex.unlock();
А как синхронизировать доступ к данным shared memory между процессами? Подозреваю что в таком случае мьютекс нужно хранить разделяемой памяти Но как конкретно это реализуется плохо представляю Подскажите пожалуйста кто знает
0
|
21.02.2017, 12:08 | |
Ответы с готовыми решениями:
73
Реализация стека строк в разделяемой памяти (MPI) Как сохранить данные контейнера в разделяемой памяти Есть ли оверхед от использования разделяемой памяти, в сравнении с глобальной? Аська на основе разделяемой памяти |
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
|
|
21.02.2017, 12:24 | 2 |
Если речь о Windows, то CreateMutex()/OpenMutex() смотри. И здесь: https://msdn.microsoft.com/en-... s.85).aspx
2
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
21.02.2017, 12:48 [ТС] | 3 |
nmcf,
Желательно кросплатформенное решение. Но в первую очередь интересуют linux-based операционки Добавлено через 18 минут Вот тут есть описание похожее на правду http://stackoverflow.com/quest... nxos-posix Надо проверить
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.02.2017, 12:54 | 4 |
Собирать спинлок на std::atomic_flag. Однако же "The C++ standard recommends (but does not require) that lock-free atomic operations are also address-free, that is, suitable for communication between processes using shared memory. ". Так что если реализация сделана не по здравому смыслу, а по стандарту, можно получить сюрприз.
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
21.02.2017, 13:43 [ТС] | 5 |
Renji,
Если не ошибаюсь реализовать спинлок можно через CAS используя ассемблерные вставки Но не знаю каково будет поведение для шаред мемори Пока думаю так: где-то в шаред куске держать флаг который обновлять CAS-ом За вариант спасибо, учту Как я понял если атомик вернул false для is_lock_free - только в этом случае нужно задействовать спинлок? И атомику нужно отдать объект созданный в шаред мемори? Верно? Добавлено через 4 минуты С другой стороны насколько я понимаю теоретически возможна ситуация когда какой-то процесс просто никогда не получит доступ к данным из за наличия спинлока. Или нет?
0
|
21.02.2017, 14:03 | 6 |
Под линуксом есть две сущности - семафор и мьютекс. Принципиальное отличие между ними в том, что мьютексы используются в условиях, когда есть какая-то память, которая видна напрямую из всех потоков исполнения, а семафоры - в условиях, когда общей памяти как бы нет. Ну и по сути это означает, что мьютексы используются для синхронизации thread'ов, а семафоры - для синхронизации process'ов. Технически мьютекс является по сути обычной переменной (т.е. куском памяти в пространстве памяти, общим для потоков), семафор на моей памяти является объектом ядра, косвенно находящимся в файловой системе (т.к. в общем случае у двух процессов нет других общих ресурсов)
Добавлено через 2 минуты См. sem_open, sem_getvalue, sem_post, sem_wait и прочие интерфейсы по работе с семафорами
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
21.02.2017, 14:06 [ТС] | 7 |
А на чем тогда основывается синхронизация? На файле? верно?
В таком случае можно ли создать мьютекс в начале разделяемой памяти и лочить/анлочить весь кусок который идет после данных мьютекса? То есть по идее получим ту же ситуацию что и с потоками ведь мьютекс будет сидеть в разделяемой памяти. Просто не хочется велосипедить если уже есть готовое решение которое можно адаптировать для работы с shared memory (готовое всмысле из коробки языка)
0
|
21.02.2017, 14:18 | 8 |
На файловой системе (возможно, просто на имени файла) основывается только создание семафора. Сам он в любом случае будет в памяти. Возможно, что под это дело автоматически создаётся страница разделяемой памяти, а может быть в памяти ядра. Я точно не знаю
В теории можно, но тонкостей работы я с ходу не знаю Если речь идёт об std::atomic - то это всего лишь переменная с атомарным доступом. Сама по себе она не является средством синхронизации. Такая операция имеет инструменты, при помощи которых создаются мьютексы или им подобные вещи. Т.е. построение мьютекса на таком объекте в любом случае будет велосипедлм (если только для этого нет специальных классов)
1
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.02.2017, 14:28 | 9 |
atomic_flag всегда lock-free.
Ну, если один из процессов захватил спинлок и повис, то да, больше никто к этому спинлоку доступа не получит. Дальше велосипедим прерывание цикла спинлока по таймеру. Но с таким уровнем велосипедостроения, проще наваять класс GlobalMutex, внутрь него всунуть батарею #ifdef проверяющую текущую ОС (смотреть макросы тут) и подсовывающую платформозависимую реализацию.
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
21.02.2017, 14:44 [ТС] | 10 |
Почему же? От части вроде является. Как я понимаю атомиком можно сделать различные данные и доступ к ним из потоков будет синхронным. Но там есть еще вспомогательные методы которые были бы полезны для реализации мьютекса-велосипеда
Добавлено через 57 секунд как это батарею? термин не ясен ))
0
|
21.02.2017, 15:02 | 11 |
Не синхронным, а атомарным. В атомарном доступе нет никаких концепций типа "освободить ресурс", "занять ресурс" и т.п. Все эти концепции - только на уровне программных соглашений в голове программиста
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
||||||
21.02.2017, 15:05 [ТС] | 12 | |||||
ну в любом случае насколько я понимаю одновременного доступа не будет
Renji, Evg, Хотел создать atomic в шаред мемори и изменять этот флаг через вызов compare_exchange_weak но обломался, нет конструктора для оператора присваивания Как то так пытался... может можно иным способом, которого я не знаю, уложить его в шаред мемори?
0
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
||||||
21.02.2017, 15:15 [ТС] | 14 | |||||
Блин можно, я ступил. Вот так надо (в прежнем примере забыл принимающую переменную сделать указателем)
Могу ли я на это полагаться? то бишь обновлять атомарно флаг в шаред мемори и полагаться на его значение занято/не занято при работе с данными в разделяемой памяти? Добавлено через 38 секунд А почему условно? А в чем? Они же вопросы синхронизации решают когда конечная цель - решить проблемы конкурентного доступа
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
||||||
21.02.2017, 15:17 | 15 | |||||
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
|
21.02.2017, 15:19 [ТС] | 16 |
Renji,
Ясно спасибо. А что скажете насчет примера с атомиком в шаред мемори который я написал выше?
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.02.2017, 15:26 | 17 |
Что надо использовать atomic_flag потому что "Unlike all specializations of std::atomic, it is guaranteed to be lock-free".
Собственно, тут вот уже готовый мютекс на atomic_flag лежит.
1
|
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
|
||||||
21.02.2017, 15:36 [ТС] | 18 | |||||
Renji,
Правильно ли я понял как это юзать?
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
||||||
21.02.2017, 15:39 | 19 | |||||
Флаг надо сначала ATOMIC_FLAG_INIT инициализировать. И освобождается он через std::atomic_flag_clear_explicit. Ну и пример если вы пропустили:
1
|
21.02.2017, 15:58 | 20 |
Потому что технически доступ может быть одновременный, но аппаратура это разрулит. В общем, не бери в голову
Мьютексы должны предоставлять интерфейсы вида "занять ресурс", "освободить ресурс и т.п.". Атомарные операции используются для реализации этих интерфейсов, но тождественно им не равны. Т.е. для реализации интерфейсов в общем случае нужно использовать атомарные операции плюс дополнительный обвес. Т.е. мьютекс - это более высокоуровневая конструкция, чем атомарныя операция Добавлено через 10 минут Что делать, если ресурс занят, вообще говоря, зависит от конкретной софтины. Если программист знает, что критическая секция короткая (по времени), то действительно можно пожужжать в цикле. Но если критическая секция длинная (например, обработка файла), то нужно спать. В противном случае будет ситуация, когда 10 потоков ломятся в один ресурс, с ресурсом работает только один поток, а остальные 9 не делают ничего полезного, но нагружают процессор Добавлено через 3 минуты Кстати, это одна из причин, почему мьютекс, реализованный с поддержкой ОС, будет более эффективным. В нём можно усыпить процесс, а разбудит его ОС, когда ресурс освободится. Если в очереди будет 10 потоков, то ОС разбудит только один. А в велосипедных реализациях будут километры кода по усыплению, периодическому просыпанию, проверке занятости и повторному засыпанию. Зато будет всё "красиво" с использованием встроенного библиотечного класса std::atomic
1
|
21.02.2017, 15:58 | |
21.02.2017, 15:58 | |
Помогаю со студенческими работами здесь
20
Запись и считывание разделяемой памяти Хранение указателей в разделяемой памяти Считать структуру из разделяемой памяти Сделать массив из 10 int в разделяемой памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |