Форум программистов, компьютерный форум CyberForum.ru

Обмен данными между процессами с помощью файлов, которые отображаются в память - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
23.11.2011, 22:35     Обмен данными между процессами с помощью файлов, которые отображаются в память #1
Классическая задача "читатели-писатели", обмен информацией должен проходить с помощью файлов, отображаемых в память. Задание уже готово, но имеет один неприятный баг - при дебагинге видно, что при вводе длинных строк программа вешается, из-за того, что первый байт файла в памяти, почему-то, устанавливается в нуль. Собственно, прошу объяснений и помощи, форумчане.

Ниже фрагменты программы, в которых идёт конкретно работа с файлом. Эта ошибка происходит где-то тут.

Код писателя:
C++
1
2
3
4
5
6
7
8
hMFile = CreateFileMapping ( (HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 99, Fn1);
StartMFile = MapViewOfFile ( hMFile, FILE_MAP_WRITE, 0, 0, 99);
char * Buf = new char[99];
do {
    cin.getline(Buf, 99);
    CopyMemory(StartMFile, Buf, 99); //Вот тут в StartMFile первый байт всё ещё установлен
    PulseEvent(hEvent1);
} while ( CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, Buf, -1, "=exit", -1) != CSTR_EQUAL );
Код читателя:
C++
1
2
3
4
5
6
7
8
hMFile = OpenFileMapping(FILE_MAP_READ, TRUE, Fn1);
StartMFile = MapViewOfFile(hMFile, FILE_MAP_READ, 0, 0, 99);
char * Buf = new char[99];
do {
    WaitForSingleObject(hEvent1, INFINITE);
    CopyMemory(Buf, StartMFile, 99); // А уже тут первый байт StartMFilе равен нулю
    cout << Name << ": we have this stuff: " << Buf << endl;
} while( CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, Buf, -1, "=exit", -1) != CSTR_EQUAL );
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.11.2011, 22:35     Обмен данными между процессами с помощью файлов, которые отображаются в память
Посмотрите здесь:

Обмен данными между двумя процессами C++
C++ Технология обмен данными между приложениями
Обмен данными между программами C++
Обмен данными между процессами в консольных приложениях C++
C++ Как организовать обмен данными между двумя разными программами?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
mc.Duck
Заблокирован
26.11.2011, 17:27     Обмен данными между процессами с помощью файлов, которые отображаются в память #2
sergeyotro, есть вероятность, что строка более 99 символов. У тебя же в массиве их только 99...
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 18:00  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #3
Цитата Сообщение от mc.Duck Посмотреть сообщение
sergeyotro, есть вероятность, что строка более 99 символов. У тебя же в массиве их только 99...
Я в курсе, да. Поэтому и написал, что проблема проявляется только с длинными строками.
Если строка больше 99 символов - то в файл, отображаемый в память, пишется только 99 и не больше.
Вопрос не в переполнении, а в том, куда пропадает 1 байт, когда клиент копирует данные себе.
mc.Duck
Заблокирован
26.11.2011, 18:24     Обмен данными между процессами с помощью файлов, которые отображаются в память #4
sergeyotro, дело в том, что у строк есть завершающий нуль-символ, поэтому в массив из 10 символов влезет только 9.
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 19:54  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #5
Цитата Сообщение от mc.Duck Посмотреть сообщение
sergeyotro, дело в том, что у строк есть завершающий нуль-символ,
[сарказм]Ох, да неужели![/сарказм]

Цитата Сообщение от mc.Duck Посмотреть сообщение
поэтому в массив из 10 символов влезет только 9.
Тогда терялся бы последний байт, а выпадает первый. О чём я, опять же, сказал в первом посте.
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 20:20     Обмен данными между процессами с помощью файлов, которые отображаются в память #6
Цитата Сообщение от sergeyotro Посмотреть сообщение
C++
1
CopyMemory(StartMFile, Buf, 99); //Вот тут в StartMFile первый байт всё ещё установлен
первый байт все еще установлен во время передачи параметров функции CopyMemory или после завершения работы этой функции, то есть во время начала выполнения строчки
C++
1
PulseEvent(hEvent1);
?
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 20:30  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #7
Цитата Сообщение от BRcr Посмотреть сообщение
первый байт все еще установлен во время передачи параметров функции CopyMemory или после завершения работы этой функции, то есть во время начала выполнения строчки
C++
1
PulseEvent(hEvent1);
?
И во время, и после.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.11.2011, 20:35     Обмен данными между процессами с помощью файлов, которые отображаются в память #8
Цитата Сообщение от sergeyotro Посмотреть сообщение
Вы же не хотите сказать, что нуль-терминированные строки символ окончания пишут своим первым байтом?
Ну я не знаю твоего формата, может ты и перевернул строки. Только как это отразится на том, какой байт терять?

Добавлено через 1 минуту
И есть ещё формат строк, в котором первый байт - счётчик, а терминального ноля нет, но в восьми битах максимально можно закодировать не 99, а 255. Если же байтов счётчика сделать два, то для всех строк короче 256-ти символов первый байт будет обнулён.
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 20:57  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #9
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну я не знаю твоего формата, может ты и перевернул строки. Только как это отразится на том, какой байт терять?
Приведенные фрагменты кода - это вся обработка строк. Нету тут подобного формата.

Цитата Сообщение от taras atavin Посмотреть сообщение
И есть ещё формат строк, в котором первый байт - счётчик, а терминального ноля нет, но в восьми битах максимально можно закодировать не 99, а 255. Если же байтов счётчика сделать два, то для всех строк короче 256-ти символов первый байт будет обнулён.
Это явно не мой случай.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 21:08     Обмен данными между процессами с помощью файлов, которые отображаются в память #10
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 1, что-то вроде этого:
C++
1
2
int * int_ptr = (int *)StartMFile;
CopyMemory( &int_ptr[1], Buf, 99 );
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 21:46  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #11
Цитата Сообщение от BRcr Посмотреть сообщение
Посмотрите вот здесь. Кажется, проблемы схожи, хоть суть их и не вполне ясна.
Попробуйте писать массив в файл с индекса 1, что-то вроде этого:
C++
1
2
int * int_ptr = (int *)StartMFile;
CopyMemory( &int_ptr[1], Buf, 99 );
Попробовал, мимо.
В данной ситуации, без поинтера, всё выглядит вот так всё:
Это происходит у "писателя"


А это происходит у читателя, первый бит в нуль.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 22:53     Обмен данными между процессами с помощью файлов, которые отображаются в память #12
Какая странная штука
Порылся в справке по WinApi функциям, что вы используете - все, по идее, должно быть в норме...
Остается, по ходу, одно: trace into в debugger'e до тех пор, пока состояние первого байта не изменится...

Добавлено через 10 минут
И, сдается мне, на крайний случай можно-таки писать в файл/читать из него, исключая первый байт.
Инкремент адреса файла в памяти на размер одного элемента массива - вполне осуществимая вещь.
sergeyotro
 Аватар для sergeyotro
0 / 0 / 0
Регистрация: 08.10.2011
Сообщений: 13
26.11.2011, 22:58  [ТС]     Обмен данными между процессами с помощью файлов, которые отображаются в память #13
Цитата Сообщение от BRcr Посмотреть сообщение
Какая странная штука
Порылся в справке по WinApi функциям, что вы используете - все, по идее, должно быть в норме...
Остается, по ходу, одно: trace into в debugger'e до тех пор, пока состояние первого байта не изменится...
Судя по всему - виной всему cin.getline(). Я добавил функцию cin.clear(), после PulseEvent(hEvent1) и теперь, при вводе строки, размером больше 99 символов, "читатели" получают строку из символов, которые идут после порога превышения размера. То есть если ввести 99 символов "а" и после ввести "asdf", то читатели получат именно "asdf".
Странное поведение cin.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2011, 23:30     Обмен данными между процессами с помощью файлов, которые отображаются в память
Еще ссылки по теме:

Обмен данными между процессами C++
Обмен данными между 2 клиентами через интернет C++
C++ Обмен данными между процессами

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
26.11.2011, 23:30     Обмен данными между процессами с помощью файлов, которые отображаются в память #14
Когда getline выбирает из потока 99 символов, она не только прекращает выборку, но и ставит потоку флаг failbit, что, вероятно, мешает функции getline получить повторный доступ к потоку на втором проходе цикла do{}while. Возможно, в этом причина изменения первого байта файла - на втором проходе цикла функция getline обламывается и пишет в буфер первый байт нулевым, затем буфер копируется в файл и читатели получают свою null-started string.
Вызов clear() очищает все флаги ошибок и на повторном доступе к потоку функция getline выбирает то, что там осталось и добросовестно пишет в буфер, который не менее добросовестно копируется в файл.
Теоретически, как-то такО_о
Yandex
Объявления
26.11.2011, 23:30     Обмен данными между процессами с помощью файлов, которые отображаются в память
Ответ Создать тему
Опции темы

Текущее время: 13:51. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru