|
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
|
|
Синхронизация доступа к разделяемой памяти21.02.2017, 12:08. Показов 12177. Ответов 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 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
|
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
|
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
|
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
|
|
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время?
Никакой пенсии. Никакого нового. . .
|
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю
Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы
Кратко. . .
|
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем
**Полевые заметки о двухнедельной совместной работе**. . .
|
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики
1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
|