| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > Разделяемая память между двумя процессами |
| Автор: Relrin 30.10.2012, 20:21 | ||||
| Стоит задача в том, чтобы сделать разделяемую память для двух процессов, в котором один процесс записывает данный (пускай какие-то рандомные числа), а второй считывает. Вся эта процедура выводится в консоль с видом типа: Первый записал: 2 Второй считал: 2 И так далее. Это сделано, но возникла проблемка следущего плана: почему после записи вывод происходит не один раз, а несколько? Быть может кто подскажет? Исходный код основной программы:
Код модуля для работы с мьютексом:
|
| Автор: Relrin 30.10.2012, 20:54 | ||||||
Вот так лучше сделать получается? Хотя смысла, определенно, согласушь тут с вами, не было:
Но меня до сих пор мучает вопрос: Почему читает из памяти N раз данные, хотя в цикле ограничивает чтение мьютекс? |
| Автор: Dem_max 31.10.2012, 05:14 |
| Мьютекс должен быть до MapViewOfFile и освобождение мьютекса после UnmapViewOfFile |
| Автор: Relrin 31.10.2012, 07:03 | ||||
Сделал вот-так, но эффект получается как и ранее(запись один раз, считывание N раз):
|
| Автор: feodorv 31.10.2012, 07:35 | ||||
Мьютекс только защищает данные, но никак не ограничивает число шагов цикла:
Если же Вы хотите сделать так, что бы первый процесс писал данные в разделяемую память, а второй процесс читал бы их оттуда только после того, как первый закончит запись, то тогда первый процесс должен сигнализировать второму, что данные есть и их можно читать. Это делается через именованное событие. Первый процесс создаёт такое событие в сброшенном виде CreateEvent( NULL, TRUE, FALSE, EVENT_NAME), второй - пытается его открыть OpenEvent(). Эти блоки кода стоит защитить разделяемым мьютексом (первоначально, при создании, занятым первым процессом и освобождаемым лишь после создания события), чтобы первый процесс точно создал событие до того, как второй будет пытаться его открыть. Тогда первый процесс пишет данные и по окончании записи сигнализирует второму SetEvent, что данные есть. Второй процесс сидит на этом событии WaitForSingleObject и ждёт, пока оно освободится, тут же переводя его в сброшенное состояние ResetEvent. И, конечно, операции чтения-записи в разделяемую память должны быть защищены мьютексом, как Вы и сделали))) Добавлено через 7 минут и 13 секунд А что это за процесс создаётся путём CreateProcess? |
| Автор: Relrin 31.10.2012, 13:04 | ||||||||||
Сделал вот так, за исключением формирования мьютекса, необходимого для создания процесса:
Там создается процесс, аналогичной этой программе. С того же места потом процесс работает парно с родительским, где один записывает, второй считывает информацию.
Это само собой понятно. Я действительно просто не могу понять одной простой вещи: почему запись и чтение работает корректно(вроде как), а вывод считанных данных происходит неоднократно? Хотя вывод дан один раз. В цикле все это находится, т.к. я хочу сделать 10 циклов записи-чтения в память. После того, как второй процесс считал данные из памяти, он выходит из мьютекса, первый на его место заходит, чтобы записать данные. То есть, по мере того, пока первый пишет, второй не должен что-либо делать, выводить, т.е. просто тупо ждать как события, так и мьютекса. То есть, в идеале я хочу видеть, чтобы в консоль выводило примерно так:
А получается:
|
| Автор: feodorv 31.10.2012, 13:50 | ||
Вы уверены, что второй процесс ждёт события? А что если вызов OpenEvent вернул NULL? Где обработка ошибок? Здесь неправильная последовательность вызовов. Нужно так:
Поставьте временные метки, когда печатаете прочтено/записано через GetTickCount. Проанализируйте вывод. К сожалению, пока нет времени вникать в тонкости происходящего... |
| Автор: Relrin 31.10.2012, 14:13 | ||
Сделал вот так теперь:
Почитав в интернете, и пройдя проверку с GetTickCount(), оказалось: когда создавался процесс, до всех операций которые будут происходить, новосозданному процессу подается заново функция main(), т.е. получалось, что плодились дочерние процессы, а следовательно и множественный вывод. Тогда возникает вопрос: а как ограничить создание процессов только одной копией исходной программы? |
| Автор: Dem_max 31.10.2012, 14:46 |
| Создаешь мьютекс, и проверяешь возвращаемое значение если ошибка то программа уже запущена. |
| Автор: feodorv 31.10.2012, 14:51 | ||||
Это из-за того самого CreateProcess??? Что-то он мне не понравился с самого начала)))
Вам же нужно два процесса, из них - один дочерний, я правильно понимаю? Тогда создавайте дочерний процесс внутри if'а, проверяющего условие на предсуществование мьютекса:
|
| Автор: Relrin 31.10.2012, 15:07 | ||||
Уже как-то получше смотрится, но все равно пока что-то не так идет: После первой записи данных идет чтение,но чтение идет не один раз, а несколько. Затем процесс завершается
Хотя, в диспетчере задач, я удостоверился, что создается лишь одна копия программы, а не несколько, как было ранее. Код таков сейчас:
|
| Автор: feodorv 31.10.2012, 15:15 |
Вот это нужно делать до CreateProcess |
| Автор: Relrin 31.10.2012, 15:22 | ||
Только что так и сделал. Результат такой же, как и в предыдущем посте. Добавлено через 2 минуты и 56 секунд Проблему решил. Переместив Sleep(500), в первом процессе до изменений события. |
| Автор: feodorv 31.10.2012, 16:42 | ||
Ну не знаю. Это похоже на гадание, не на программирование. Нужно бы разобраться, почему происходит выход из WaitForSingleObject, сделать контроль ошибок и т.д. Но если и так удовлетворяет, то ладно. Мои поздравления |
| Автор: Dem_max 1.11.2012, 06:42 | ||
Контроль ошибок для дураков, а не для настоящих программистов. |