|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
Синхронизация доступа к разделяемой памяти21.02.2017, 12:08. Показов 12127. Ответов 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 в разделяемой памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Знаете, от чего появляется стресс?
kumehtar 15.07.2026
Стресс появляется оттого, что вы, зная как поступить правильно, делаете наоборот.
Ларри Уингет
|
Нас бьют, а мы крепчаем? Какая чушь!
kumehtar 15.07.2026
Вот это вот бытующее мнение, что человек меняется только под действием проблем, всегда считал вредоносным. Поверь, от проблем у людей появляются не изменения, а нервное расстройство и ПТСР. А. . .
|
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров
В текущей версии модели успешно реализован ключевой механизм. . .
|
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям
Реализованные компоненты:
Механизм закисления почвы через протонную помпу
Конкуренция между типами микориз
pH как триггер сукцессии
C/ P соотношение. . .
|
|
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
|
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
|
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы
## О чём эта статья
В процессе построения ОДУ-модели (система дифференциальных. . .
|
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет)
Содержание проекта
Симуляция вековой (50 лет) экологической сукцессии в почве леса
Основные участники: АМ-гриб, ЭКМ-гриб,. . .
|