|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
Синхронизация доступа к разделяемой памяти21.02.2017, 12:08. Показов 12154. Ответов 73
Метки нет (Все метки)
Когда потоки являются дочерними по отношению к процессу тут все просто - объект мьютекса находится в общей памяти и используя этот объект можно делать mutex.lock() определенной секции а при завершении работы mutex.unlock();
А как синхронизировать доступ к данным shared memory между процессами? Подозреваю что в таком случае мьютекс нужно хранить разделяемой памяти Но как конкретно это реализуется плохо представляю Подскажите пожалуйста кто знает
0
|
|
| 21.02.2017, 12:08 | |
|
Ответы с готовыми решениями:
73
Реализация стека строк в разделяемой памяти (MPI)
Есть ли оверхед от использования разделяемой памяти, в сравнении с глобальной? |
| 21.02.2017, 15:59 | |
|
Не по теме: А разве с помощью new можно выделить память, которая будет доступна другим процессам? Или это особенность Linux?
0
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||
| 21.02.2017, 16:25 [ТС] | ||||
|
Насколько я понимаю весь отрезок шаред памяти будет захвачен одним процессом пока он его не освободит, так? Добавлено через 26 секунд
0
|
||||
|
|
||
| 21.02.2017, 16:28 | ||
|
1
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|||||||
| 21.02.2017, 16:46 [ТС] | |||||||
|
но при таком вызове
как передать нужный адрес
0
|
|||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 21.02.2017, 17:23 [ТС] | |
|
Evg,
Тогда не понимаю, как применить этот пример для того что бы получить то, что мне нужно. Насколько я понял он подходит только для тех случаев когда у одного процесса есть много потоков Мне же нужен некоторый атомарно изменяемый процессами флаг на который я могу ориентироваться при чтении/записи из шаред мемори. Пока думаю подходит вариант описанный тут: Синхронизация доступа к разделяемой памяти Если более опытные видят что я чего-то не понимаю, прошу меня поправить.
0
|
|
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||
| 21.02.2017, 19:32 | ||
|
1
|
||
|
|
||
| 21.02.2017, 20:02 | ||
|
"Нормальная" работа с разделяемым ресурсом выглядит, например, так. Есть некий ресурс, который обладает свойсвтом, что одновременно с ним разрешено работать только одному потоку/процессу. Это может быть файл, это может быть массив, это может быть сетевое соединение, принципиальной разницы нет. В каждому такому ресурсу пристраивается некий семафор, который в простом случае состоит из двух положений: занято и свободно (именно к этому семафору нужно прикладывать атомарные операции и прочие велосипеды). Поток хочет использовать файл, перед тем, как его использовать, он смотрит на семафор. Если семафор в положении "занято", значит поток либо спит, либо занимается своими делами, либо ковыряет в носу, ожидая освобождения семафора. Как только семафор переключился в положение "свободно", поток нажимает на кнопку "попробуй занять семафор" и получает в ответ результат "ты занял семафор" либо "ты не занял семафор, т.к. какой-то параллельный поток нажал кнопку раньше тебя". В обоих случаях семафор встал в положение "занято". Во втором случае (не успел занять) поток опять ковыряет в носу. В первом случае (успел занять) поток приступает к работе с файлом, делает то, что нужно, после чего нажимает на кнопку "освободить семафор". Семафор переходит в состояние "свободно", а поток продолжает заниматься своими локальными делами Это один из простейших вариантов работы. В каждом конкретном случае такая модель может выглядеть по разному. Семафоров может быть несколько. Они могут быть более, чем с двумя состояниями. Т.е. твоя задача состоит в том, чтобы запрограммировать семафор, описать интерфейсы, читающие состояние ("занято" или "свободно"), "попробуй занять семафор", "освободить семафор", может что-то ещё нужно. Этот объект-семафор должен находиться в разделяемой памяти, т.е. быть доступным для всех процессов
1
|
||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||
| 21.02.2017, 21:28 [ТС] | ||
|
Вот я опасаюсь следующего: Если предположим мы обрабатываем сетевое соединение в процессе и какой то процесс очень невезучий и все никак не может захватить доступ к критической секции. Выходит что клиент может ждать условно говоря бесконечно. Чего делать? Таймауты лепить? Или есть другие решения? И еще меня беспокоит следующее: насколько я знаю менеджеры задач ОС не любят задачи которые работают в "холостую" и могут понижать им приоритет выполнения при смене с них контекста (не уверен, но где-то об этом читал). Вот спинлок как раз работает много в холостую. Так же сталкивался с мнением что работающие в холостую потоки "засыпают" т.е перестают что-то делать. В таком случае интересно если поток процесса уснет то кто будет проверять освободилась ли критическая секция? И еще один вопрос: Представим что некий вызов пытается захватить мьютекс по вашему примеру. Но мне не важно он захватит его или нет, то есть эту операцию можно будет попробовать выполнить в следующий раз если в этом возникнет необходимость. В таком случае как я понимаю цикл не нужен? Можно просто в функции посмотреть если !atomic_flag_test_and_set_explicit значит прерываем работу функции и так в следующий раз когда появится необходимость в данном вызове. Такое решение конкретно для данной ситуации не считается ошибкой? Evg, Вот мне нужно все то что ты написал
0
|
||
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||||
| 21.02.2017, 21:39 | ||||
|
1
|
||||
|
|
|||||||||
| 21.02.2017, 21:50 | |||||||||
|
При этом вариант ковыряния в носу (жужжать или спать) - это заранее запрограммированное действие, а вовсе не результат деятельности планировщика задач
1
|
|||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||
| 21.02.2017, 22:06 [ТС] | ||||
|
Вот еще что интересно: при чтении данных из контейнера тоже нужно мьютекс захватывать? Я думаю что нужно потому что если в читаемое значение пишет другой процесс например int, то может возникнуть ситуация что пишущий поток успеет положить туда например только 2 байта и прочитаем мы не понятно что. Ок если при чтении тоже нужно захватывать блокировку то что делать в следующей ситуации: Предположим что запись в контейнер происходит один раз для каждого ключа, здесь для чтения ставить блокировку не вижу смысла. Вот думаю не писать int а сделать pair, где first будет флагом bool и равен true после успешной записи а second значением. А при чтении уже проверять если флаг тру - значит значение есть и его можно читать. Но тут снова проблема - выходит из за одной записи при каждом чтении нужно будет проверять данный флаг что не эффективно. Если флаг один раз был тру - то больше его проверять смысла нет, но при таком раскладе придется. Можете что нибудь посоветовать по этому поводу? Добавлено через 10 минут
0
|
||||
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
|||
| 21.02.2017, 22:18 | |||
|
Если же процессы постоянно лезут в глобальные данные в шаред мемори, значит у вас ошибка проектирования многопоточного приложения.
0
|
|||
|
|
||||||||
| 21.02.2017, 22:29 | ||||||||
|
Скорее всего внутри реализации используется поддержка ОС. Либо какая-то самопальная реализация очереди, чтобы гарантированно исключить ситуации, когда ты долбишься в семафор и никак не захватишь Добавлено через 1 минуту Для ptread_mutex_lock завтра попробую посмотреть, что в glibc'ях сделано
1
|
||||||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
||||||||||||||||
| 21.02.2017, 22:47 [ТС] | ||||||||||||||||
Добавлено через 7 минут
0
|
||||||||||||||||
|
|
|||||
| 21.02.2017, 23:02 | |||||
|
C++ atd::atomic a, b; a.store (1, std::memory_order_relaxed); b.store (2, std::memory_order_relaxed); Добавлено через 4 минуты Пардон, про relaxed я наврал. Тут какая-то другая семантика должна быть. Т.е. та, которая нам обеспечит правильный порядок операций записи в память Добавлено через 3 минуты Возможно, должно быть так. std::atomic'ом должен быть только флаг. Запись значения "готово" в флаг должна выполняться с семантикой release (это обеспечит исполнение тех записей в память, что стоят выше по коду). Чтение (проверка) флага должно быть с семантикой acquire. Но тут меня надо перепроверять Добавлено через 4 минуты Т.е. что-то типа того: C++ struct Data { std::atomic<bool> flag; int data; }; struct Data *Element; // Запись элемента в одном потоке Element->data = val; Element->flag.store (true, memory_order_release); // Чтение элемента в другом потоке if (Element->flag.load (memory_order_acquire) == true) val = Element->data;
0
|
|||||
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 21.02.2017, 23:15 [ТС] | |
|
Evg,
Поищу инфу про эти семантики, спасибо! Не по теме:
0
|
|
|
|
|
| 22.02.2017, 09:19 | |
|
http://en.cppreference.com/w/c... mory_order
Добавлено через 10 минут https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
1
|
|
|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
| 22.02.2017, 11:37 [ТС] | |
|
Evg,
Спасибо за ссылки, почитаю. Я подумал насчет перестановок про которые ты говорил. Думаю компилятор может переставить последовательность выполнения в целях оптимизации, если он думает, что это не нарушит общую логику выполнения. Иначе последовательный код был бы всегда не надежным и программы "то работали бы как задумано, то нет". Учитывая это я думаю все таки можно сначала писать данные с локом, но на чтении не лочить доступ а просто смотреть флаг, нет?
0
|
|
| 22.02.2017, 11:37 | |
|
Аська на основе разделяемой памяти Запись и считывание разделяемой памяти Хранение указателей в разделяемой памяти Считать структуру из разделяемой памяти Сделать массив из 10 int в разделяемой памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Нейтральные знания ..., ... чистая наука. Пока что-то проходит модерацию на Хабре, стоит развить мысль ...
Hrethgir 20.07.2026
К таким радикальным взглядам я конечно в той публикации не приходил, но чтобы скоротать вечер, решил углубиться немного.
1. Почему показания термометра заряжены целью?
Цель заложена в самом. . .
|
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
|
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
|
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения.
https:/ / habr. com/ ru/ sandbox/ 295048/
По ссылке 403. Не очень информативно такую ссылку постить.
Запись от Usaga размещена Сегодня в 06:46 . . .
|
|
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
|
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано
Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
|
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано
Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
|
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0)
Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона
Уважаемые коллеги!
В продолжение. . .
|