Доброго времени суток! Собственно вынужден отклониться на время от своего проекта... по причине загрузки на работе. Но данный вопрос пригодится для продолжения. Ранее по рекомендации участников этого форума скачал книгу "ВЗАИМОДЕЙСТВИЕ ПРОЦЕССОВ" Стивенса. Столкнулся же с проблемой доступа к данным уже запущенного процесса из другого вновь запускаемого. Сразу оговорюсь, что уже запущенный процесс уже предоставляет данные в разделяемой памяти для доступа к ней другим процессам... но что-то никак не могу вкурить. Собственно "лоджик" от SEGNETICS предоставляет данные в разделяемой памяти. Надо иметь доступ к ней из другого процесса в SSH сессии через программу на Си. Обратился к https://habrahabr.ru/post/122108/ содрал примеры и сделал кое какой тест: shared_mem.zip Но... как говорил выше не очень вкурил идею механизма... ну или очень не вкурил. Был бы благодарен за пример, где сначала запускаем одну программу, которая что-то делает с данными в этой разделяемой памяти, а потом запускаю другую программу, которая имеет доступ к данным в этой разделяемой памяти. Хочу оговориться, что данные через файл или сокет мне понятны. вот опыты из теста w1 (coздаём): Код (Bash): igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 create test Shared memory filled in. You may run './w1 print' to see shared memory value. вот читаем: Код (C++): igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 print Got from shared memory: test Черз час снова читаем: Код (Bash): igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 print Got from shared memory: test Вот удаляю: Код (Bash): igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 unlink Вот снова читаю после удаления: Код (Bash): igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 print shm_open: No such file or directory Как найти и где эта shm_open: No such file or directory в какой директории. Одним словом никак не пойму. Заранее спасибо.
Почему бы разделяемую память не назвать файлом? Фактически это тоже файл, но в оперативной памяти, а не на диске. Когда система не находит по имени этот объект-файл, выдает единообразное сообщение. Кроме того: Так что разделяемая память может выглядеть как файл на диске.
Ну вот видите... Вы и приоткрыли мне глаза немного сказав про /dev/shm. Зпустив пример увидел там: Код ( (Unknown Language)): igor@debian-i:~$ ls /dev/shm my_shared_memory pulse-shm-1526888764 pulse-shm-1641381009 pulse-shm-2040980075 pulse-shm-2631088815 pulse-shm-3835178020 sem.my_named_semaphore где (тоесть в my_shared_memory) находится: Код (Bash): test^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ то есть его содержимое в текстовом виде. После igor@debian-i:/home/ext_projects/shared_mem/w1$ ./w1 unlink : Код (Bash): igor@debian-i:/home/ext_projects/shared_mem/w1$ ls /dev/shm pulse-shm-1526888764 pulse-shm-1641381009 pulse-shm-2040980075 pulse-shm-2631088815 pulse-shm-3835178020 sem.my_named_semaphore Вот бы нормальный пример работы! И то Спасибо Вам! Теперь знаю где искать!
Чем вас этот пример не устраивает? Разные процессы по известному имени обращаются к разделяемой памяти. Механизм виртуализации отображает разделяемую область физической памяти в адресное пространство виртуальной памяти процесса. В разных процессах это могут быть разные адреса, но адреса ячеек физической памяти одни и та же. Прелесть в том, что данные не надо копировать между процессами. Процесс работает с этой памятью как со своей, но предпринимая некоторые меры предосторожности, типа синхронизации доступа с помощью семафоров и т.п.
С mutex (Mutual Exclusive lock - взаимоисключающая блокировка) непосредственно не работал. В C++ для этого есть класс, который автоматически захватывает блокировку когда объект создается в стеке и автоматически освобождает, когда объект удаляется из стека. Положим есть функции A и B которые выполняются в разных процессах или в разных потоках одного процесса и читают/пишут в область разделяемой памяти из ячеек i и j. Казалось бы, чтение безопасная операция, однако, если в системе есть пишущий процесс, он может приступить к изменению ячеек i и j. Положим, i и j равны 1, а установить их нужно в 2. И так. A: i = 2; B: k = i, l = j. A: j = 2 B: k == 2, l != 2 // Ошибка!!! Данные не согласованы . Тогда что мы делаем. A: lock(MTX) // Получили блокировку MTX A: i = 2 B: lock(MTX) // Мутекс MTX уже занят. Ждем A: j = 2 A: release(MTX) // Освобождаем MTX B: // процесс разблокировался B: k = i, l = j. B: k == 2, l == 2 // Все хорошо. B: release(MTX) // Освобождаем MTX К сожалению при таком подходе одновременно два читателя встанут в очередь за MTX. Если читателей много имеет смысл применить более сложные механизмы. Тут наверное стоит поискать специальную литературу.
В работе с потоками всегда работаю с мютексами. Вот в разных независимых процессах опыта нет, когда один при включении в работе, а другой может быть запущен в любой момент... или перезапущен. Хотя Вы вчера указали где искать эту память. Остаётся найти "синхронизацию" либо через семафор... либо мютекс.
Внутри процесса легко использовать безъимянные мютексы или семафоры. Адрес мютекса доступен всем потокам. Для IPC (Inter-Process Communication) нужно использовать именованные мютексы, семафоры, поскольку они живут в операционной системе. Процесс может получить их хэндл только по имени. Наверняка локи так же отображаются в файловую ситему. Еще вариант - координирующий процесс, который обеспечивает доступ к своей внутренней неразделяемой памяти через вызовы процедур. Но тут много накладных расходов возникает.
Для своего кода буду иметь ввиду... но для чужого SMLogix(Segnetics) придётся подстроится (благо примеры прилагаются), но не знал того, что Вы мне вчера указали. Правда надеялся, что кто-то применял эти методы - потому и ждал простого примера кода.
Тут все же форум по микроконтроллерам, а не по системному программированию. Думаю, если погуглить названия системных функций, вы быстро найдете и примеры кода и грабли, на которые наступают программисты и баги.
Вы уж простите... но это собираюсь применять для Raspberry Pi (правда не только для малины). Потому тут и поднял эту тему. Вот что у меня получилось (взято из примеров и переделано для себя - тоже пример): shared_mem.zip Коментарий в doc.txt