Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Доступ к массиву из разніх потоков  (Прочитано 19731 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
elder
Интересующийся

ua
Offline Offline

« : 20-02-2012 21:00 » new

Доброго времени суток.
Эта тема нехарактерна, т.к. к Вам обращается не программист, а разработчик. Случилось так, что мне приходится намечать стратегию решения программной части комплекса. Итак, проблема.
Есть Win32 приложение, которое:
1. Реализует интерфейс пользователя, задающий входные значения для задачи.
2. Создает двумерный массив (этак 8-12 Мб) float-значений.
3. Инициирует и запускает процесс, работающий по тикам таймера (системного или аппаратного с инструментальной платы).
4. Передает входные значения (структура - ?) и доступ к массиву запущенному процессу.
5. И ... замолкает, т.е. вообще ничего не делает на время работы процесса таймера.

Процесс по тикам таймера:
1. По результатам предыдущей итерации вычисляет текущие результаты.
2. Заполняет ими i-тую колонку массива результатов.
3. Ждет следующего прерывания (тика).
4. После выполнения n заданных итераций сообщает об этом основному приложению.
Шаг итерации - 1 мс +- 20 мкс

Win32 приложение:
1. Удаляет процесс.
2. Производит обработку массива результатов.

Хотелось бы получить совет по общей стратегии построения приложения и по методам доступа к описанным объектам в памяти из обоих процессов.
Разработка ведется под WinXP SP3.
Инструментарий - VS 2008 + Win RTX 8.1.2/



Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 20-02-2012 21:12 » 

Не очень ясное описание в п.п. 3-5 первого блока.
Из общего описания следует, что одновременного доступа к массиву нет, а также есть последовательное выполнение процессов. Если первый процесс на время работы второго ничего больше не делает, есть смысл заблокировать его в ожидании результата из второго процесса.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 20-02-2012 21:24 » 

А где разные потоки?

Ставить lock (взводить флаг) занятости массива. Т.е построить систему светофоров.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
zubr
Гость
« Ответ #3 : 21-02-2012 02:48 » 

1. Основной процесс создает блок расшаренной памяти (файлмаппинг), куда помещает нужную структуру данных (массив, входные данные).
2. Основной процесс запускает дополнительный процесс и ждет завершения его выполнения (WaitForSingleObject).
3. Дополнительный процесс получает доступ к блоку расшаренной памяти. В процессе работы производит необходимые манипуляции с этим блоком (изменяет массив). После окончания работы, закрывается.
4. Основной процесс, дождавшись закрытия дополнительного, обрабатывает данные из массива, после чего запускает дополнительный процесс - цикл повторяется.

Для данной задачи никакой синхронизации не надо.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 21-02-2012 03:47 » 

Точнее, ожидание завершения созданного процесса и есть синхронизация. Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
elder
Интересующийся

ua
Offline Offline

« Ответ #5 : 21-02-2012 06:19 » 

Всем спасибо за советы.
Действительно, в любой момент времени работает ТОЛЬКО ОДИН процесс. Синхронизации не нужно.
Подскажите, не будет ли проблем с выделением больших объемов памяти и с доступом к ней из обоих процессов. НЕ ОДНОВРЕМЕННЫМ!


Добавлено через 2 минуты и 54 секунды:
И еще один вопрос. Может, кто работал с RTX от IntervalZero. Как лучше строить задачу, как .exe или .rtss ?
« Последнее редактирование: 21-02-2012 06:22 от elder » Записан
zubr
Гость
« Ответ #6 : 21-02-2012 07:05 » 

Объем памяти ограничен установленным размером оперативной памяти (до 4 гиг), ну и конечно должно быть достаточно свободного места на диске.
И есть нюанс при чтении-записи в расшаренную память для больших объемов - надо писать читать (MapViewOfFile) частями размером dwAllocationGranularity (структура SYSTEM_INFO GetSystemInfo).
Записан
elder
Интересующийся

ua
Offline Offline

« Ответ #7 : 21-02-2012 07:37 » 

zubr, есть проблема.
1. Основной процесс создает блок расшаренной памяти (файлмаппинг), куда помещает нужную структуру данных (массив, входные данные).
Насколько я понимаю, FileMapping по усмотрению системы может быть сброшен на диск. А дисковые операции выполняются не очень быстро. А шаг итерации - 1мс. Можем не успеть.
Нельзя ли гарантированно разместить большой массив данных в ОЗУ? Конечно, при наличии такового, это уже другой вопрос.
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 21-02-2012 07:50 » 

elder, возможность компиляции exe модуля в RTX - это, по моему, просто небольшой костыль исключительно для возможности отладки в VS. да и то, помоему сейчас они интегрировали нормальный отладчик.

PS 8 Мб это не очень большой участок.
по поводу организации расшаренной памяти - если будет время посмотрю на работе...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
zubr
Гость
« Ответ #9 : 21-02-2012 08:08 » 

Цитата
Насколько я понимаю, FileMapping по усмотрению системы может быть сброшен на диск. А дисковые операции выполняются не очень быстро. А шаг итерации - 1мс. Можем не успеть.
Нельзя ли гарантированно разместить большой массив данных в ОЗУ? Конечно, при наличии такового, это уже другой вопрос.
Также как и другие страницы памяти. Менеджер памяти может сбрасывать/подгружать на/с диск/а страницы расшаренной памяти в зависимости от необходимости. Многое зависит от размера ОЗУ. Как вариант, если ОЗУ достаточно, задавать высокий приоритет своим процессам, но это может:
1. Подвесить систему.
2. Все равно 100% гарантии не будет.
Чтобы массив гарантированно находился в ОЗУ, его надо размещать из под ядра в неперемещаемой памяти.
Записан
elder
Интересующийся

ua
Offline Offline

« Ответ #10 : 21-02-2012 09:04 » 

Также как и другие страницы памяти. Менеджер памяти может сбрасывать/подгружать на/с диск/а страницы расшаренной памяти в зависимости от необходимости. Многое зависит от размера ОЗУ.
Я выскажу два предложения, и хотел бы услышать Ваши "За-Против"
1. Запретить pagefile.sys
Компьютер будет использоваться ТОЛЬКО для описанной задачи. Кроме того, ОС будет обрезана (отключены все ненужные службы и компоненты). И имея к примеру 4 гига ОЗУ, можно позволить себе работать без файла подкачки. При этом массив данных задачи будет располагаться в ОЗУ и будет обеспечен быстрый доступ к данным.
2. Создать в системе RAM disk и работать не с массивом данных, а с файлом на нем. Это должно быт достаточно быстро. Как тогда будет выглядеть доступ к файлу из разных процессов? Доступ разнесенный во времени. Один процесс пишет файл до конца, только после этого второй процесс читает данные.

Не хотелось бы переоткрывать файл в другом процессе. Передать открытый файл можно?
« Последнее редактирование: 21-02-2012 09:09 от elder » Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #11 : 21-02-2012 10:12 » 

Если не ошибаюсь, есть функция VirtualLock() которая позволяет запретить выгрузку памяти в swap.
Записан
elder
Интересующийся

ua
Offline Offline

« Ответ #12 : 21-02-2012 10:22 » 

darkelf спасибо.

http://www.podgoretsky.com/ftp/docs/Delphi/Memory/virtual/VirtualLock.html
Функция VirtualLock фиксирует указанный фрагмент виртуального адресного пространства процесса в физической памяти. При этом обеспечивается то обстоятельство, что при последующем доступе к указанному диапазону не будет происходить ображение к файлу подкачки.

Записан
zubr
Гость
« Ответ #13 : 21-02-2012 10:47 » 

Не уверен, что с расшаренной памятью поможет VirtualLock. Дело в том, что VirtualLock блокирует память в контексте текущего процесса, а вот как она работает с расшаренной памятью - хз, в MSDN об этом ничего не сказано.
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #14 : 21-02-2012 11:20 » 

По логике должно работать, т.к. разделяемая память отличается от неразделяемой лишь тем, что к ней имеет доступ более одного процесса каждый через своё отображение в адресном пространстве. Физические страницы должны быть одни и те-же и блокироваться должны именно они, если не указано что-то типа Copy On Write aka COW. А в реальности - надо проверять и/или искать в подтверждение/опровержение в google.
« Последнее редактирование: 21-02-2012 11:29 от darkelf » Записан
elder
Интересующийся

ua
Offline Offline

« Ответ #15 : 21-02-2012 12:15 » 

По поводу VirtualLock вроде бы раньше была статья в MSDN, но где-то исчезла. И там ничего хорошего... Насколько я помню, в определенных условиях, когда системе совсем туго, она может все-таки сбросить в pagefile.
А как по поводу моего предыдущего поста? (#11  21.02   09:04) Какие есть мнения?
Записан
darkelf
Молодой специалист

ua
Offline Offline

« Ответ #16 : 21-02-2012 13:27 » 

elder, можно попытаться передать открытый файл через наследование дескрипторов файлов, если вы второй процесс запускаете из первого.
Насколько я понял разделяемая память в pagefile не попадает, т.к. на самом деле для неё создаётся свой файл, и своп выполняется уже туда, но тут я могу ошибаться.
« Последнее редактирование: 21-02-2012 13:46 от darkelf » Записан
zubr
Гость
« Ответ #17 : 21-02-2012 13:30 » 

Я выскажу два предложения, и хотел бы услышать Ваши "За-Против"
1. Запретить pagefile.sys
Компьютер будет использоваться ТОЛЬКО для описанной задачи. Кроме того, ОС будет обрезана (отключены все ненужные службы и компоненты). И имея к примеру 4 гига ОЗУ, можно позволить себе работать без файла подкачки. При этом массив данных задачи будет располагаться в ОЗУ и будет обеспечен быстрый доступ к данным.
2. Создать в системе RAM disk и работать не с массивом данных, а с файлом на нем. Это должно быт достаточно быстро. Как тогда будет выглядеть доступ к файлу из разных процессов? Доступ разнесенный во времени. Один процесс пишет файл до конца, только после этого второй процесс читает данные.

Не хотелось бы переоткрывать файл в другом процессе. Передать открытый файл можно?
1. Имеет смысл.
2. В принципе можно вообще отказаться от расшаренной памяти. Дополнительный процесс сохраняет данные в залоченный блок памяти. По окончании работы, сохраняет их в файл. Основной процесс открывает файл, читает данные из него в свой буфер и работает с ним. И т. д.
И зачем передавать открытый файл? Не вижу сложностей в открытии-закрытии файла.
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 21-02-2012 14:14 » 

elder, все вышеописанные советы верны.... вот только...
вот только они почти не относятся к вашему случаю использования RTX Ага

еще раз: RTX - ЭТО НЕ WINDOWS!!!!!!!!!!!!!!!!!!!!!!

вам нужны функции RtCreateSharedMemory/RtOpenSharedMemory
подробности взаимодействия RTX процессов с процессами windows - смотрите в RTX-SDK. раздел Interprocess Communication

PS да, имейте в виду, что в процессах RTX фактически невозможны вызовы функций windows(без потери детерминированности времени).
 ни графики, ни стандартных функций windows - ничего. абсолютный минимум.
и даже никаких сторонних скомпилированных библиотек (если они не в исходных кодах поставляются, да и то - танцы)
считайте ее отдельной независимой ОС, которая позволяет через специальные функции передавать данные и события - другой OC(win).
« Последнее редактирование: 21-02-2012 14:29 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elder
Интересующийся

ua
Offline Offline

« Ответ #19 : 21-02-2012 20:10 » 

Ochkarik, я знаю, что RTX - это не Windows.
Но если у меня есть Windows-процесс (интерфейсная часть программы) и RTX-процесс (вычисления в реальном времени и заполнение массива результатов), то могу ли я расшарить память из Windows-процесса (ф-и FunctionName) , а получить доступ к ней из RTX (ф-и RtFunctionName)?
Записан
Ochkarik
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 21-02-2012 21:01 » 

да, используя функции RtCreateSharedMemory/RtOpenSharedMemory
В rtx они вызываются напрямую, в Win32 - через подключаемую интерфейсную библиотеку, предоставляющую интерфейс RTKAPI.
кроме того в раздел функций взаимодействия с win32 входят события, семафоры и мьютексы.
RTX SDK Reference > API Function Call Reference > Windows Driver IPC API (RTKAPI) Reference

полный хелп(скорее всего по RTX2011 версии)
RTX Help online

PS думать о том свопируемая это память или нет - не имеет смысла. данные функции на это рассчитаны и выделяют несвопируемую память.
« Последнее редактирование: 21-02-2012 21:13 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines